@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
package/dist/pages/index.astro
CHANGED
|
@@ -13,29 +13,131 @@ import BookList from '../components/site/BookList.astro';
|
|
|
13
13
|
import {
|
|
14
14
|
getPublishedAgents,
|
|
15
15
|
getPublishedBooks,
|
|
16
|
+
getPublishedDecisions,
|
|
16
17
|
getPublishedNotes,
|
|
17
18
|
getPublishedObjectives,
|
|
18
19
|
getPublishedPeople,
|
|
20
|
+
getPublishedProposals,
|
|
19
21
|
getPublishedQuestions,
|
|
20
22
|
resolveContributorsForEntries,
|
|
21
23
|
} from '../utils/hub-content';
|
|
24
|
+
import {
|
|
25
|
+
isPublishedRuntimeContentMode,
|
|
26
|
+
loadPublishedCollection,
|
|
27
|
+
loadPublishedEntry,
|
|
28
|
+
metadataFromPublishedContent,
|
|
29
|
+
resolvePublishedContributor,
|
|
30
|
+
} from '../utils/site-content-runtime';
|
|
22
31
|
import { siteModelRendered } from '../utils/site-models.js';
|
|
23
32
|
|
|
24
33
|
const notesRendered = siteModelRendered('notes');
|
|
25
34
|
const questionsRendered = siteModelRendered('questions');
|
|
26
35
|
const objectivesRendered = siteModelRendered('objectives');
|
|
36
|
+
const proposalsRendered = siteModelRendered('proposals');
|
|
37
|
+
const decisionsRendered = siteModelRendered('decisions');
|
|
27
38
|
const peopleRendered = siteModelRendered('people');
|
|
28
39
|
const agentsRendered = siteModelRendered('agents');
|
|
29
40
|
const booksRendered = siteModelRendered('books');
|
|
30
41
|
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
const publishedRuntime = isPublishedRuntimeContentMode();
|
|
43
|
+
const notes = notesRendered
|
|
44
|
+
? (
|
|
45
|
+
publishedRuntime
|
|
46
|
+
? (await loadPublishedCollection(Astro.locals, 'notes')).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
|
47
|
+
: await getPublishedNotes()
|
|
48
|
+
).slice(0, 3)
|
|
49
|
+
: [];
|
|
50
|
+
const questions = questionsRendered
|
|
51
|
+
? (
|
|
52
|
+
publishedRuntime
|
|
53
|
+
? (await loadPublishedCollection(Astro.locals, 'questions')).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
|
54
|
+
: await getPublishedQuestions()
|
|
55
|
+
).slice(0, 2)
|
|
56
|
+
: [];
|
|
57
|
+
const objectives = objectivesRendered
|
|
58
|
+
? (
|
|
59
|
+
publishedRuntime
|
|
60
|
+
? (await loadPublishedCollection(Astro.locals, 'objectives')).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
|
61
|
+
: await getPublishedObjectives()
|
|
62
|
+
).slice(0, 2)
|
|
63
|
+
: [];
|
|
64
|
+
const proposals = proposalsRendered
|
|
65
|
+
? (
|
|
66
|
+
publishedRuntime
|
|
67
|
+
? (await loadPublishedCollection(Astro.locals, 'proposals')).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
|
68
|
+
: await getPublishedProposals()
|
|
69
|
+
).slice(0, 2)
|
|
70
|
+
: [];
|
|
71
|
+
const decisions = decisionsRendered
|
|
72
|
+
? (
|
|
73
|
+
publishedRuntime
|
|
74
|
+
? (await loadPublishedCollection(Astro.locals, 'decisions')).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
|
75
|
+
: await getPublishedDecisions()
|
|
76
|
+
).slice(0, 2)
|
|
77
|
+
: [];
|
|
78
|
+
const questionContributors = publishedRuntime
|
|
79
|
+
? new Map(
|
|
80
|
+
await Promise.all(
|
|
81
|
+
questions.map(async (question) => {
|
|
82
|
+
const detail = await loadPublishedEntry(Astro.locals, 'questions', question.id);
|
|
83
|
+
const contributor = await resolvePublishedContributor(
|
|
84
|
+
Astro.locals,
|
|
85
|
+
metadataFromPublishedContent(detail?.content)?.primaryContributor,
|
|
86
|
+
);
|
|
87
|
+
return [question.id, contributor ?? null] as const;
|
|
88
|
+
}),
|
|
89
|
+
),
|
|
90
|
+
)
|
|
91
|
+
: await resolveContributorsForEntries(questions);
|
|
92
|
+
const objectiveContributors = publishedRuntime
|
|
93
|
+
? new Map(
|
|
94
|
+
await Promise.all(
|
|
95
|
+
objectives.map(async (objective) => {
|
|
96
|
+
const detail = await loadPublishedEntry(Astro.locals, 'objectives', objective.id);
|
|
97
|
+
const contributor = await resolvePublishedContributor(
|
|
98
|
+
Astro.locals,
|
|
99
|
+
metadataFromPublishedContent(detail?.content)?.primaryContributor,
|
|
100
|
+
);
|
|
101
|
+
return [objective.id, contributor ?? null] as const;
|
|
102
|
+
}),
|
|
103
|
+
),
|
|
104
|
+
)
|
|
105
|
+
: await resolveContributorsForEntries(objectives);
|
|
106
|
+
const proposalContributors = publishedRuntime
|
|
107
|
+
? new Map(
|
|
108
|
+
await Promise.all(
|
|
109
|
+
proposals.map(async (proposal) => {
|
|
110
|
+
const detail = await loadPublishedEntry(Astro.locals, 'proposals', proposal.id);
|
|
111
|
+
const contributor = await resolvePublishedContributor(
|
|
112
|
+
Astro.locals,
|
|
113
|
+
metadataFromPublishedContent(detail?.content)?.primaryContributor,
|
|
114
|
+
);
|
|
115
|
+
return [proposal.id, contributor ?? null] as const;
|
|
116
|
+
}),
|
|
117
|
+
),
|
|
118
|
+
)
|
|
119
|
+
: await resolveContributorsForEntries(proposals);
|
|
120
|
+
const decisionContributors = publishedRuntime
|
|
121
|
+
? new Map(
|
|
122
|
+
await Promise.all(
|
|
123
|
+
decisions.map(async (decision) => {
|
|
124
|
+
const detail = await loadPublishedEntry(Astro.locals, 'decisions', decision.id);
|
|
125
|
+
const contributor = await resolvePublishedContributor(
|
|
126
|
+
Astro.locals,
|
|
127
|
+
metadataFromPublishedContent(detail?.content)?.primaryContributor,
|
|
128
|
+
);
|
|
129
|
+
return [decision.id, contributor ?? null] as const;
|
|
130
|
+
}),
|
|
131
|
+
),
|
|
132
|
+
)
|
|
133
|
+
: await resolveContributorsForEntries(decisions);
|
|
134
|
+
const people = peopleRendered ? (publishedRuntime ? (await loadPublishedCollection(Astro.locals, 'people')) : await getPublishedPeople()).slice(0, 2) : [];
|
|
135
|
+
const agents = agentsRendered ? (publishedRuntime ? (await loadPublishedCollection(Astro.locals, 'agents')) : await getPublishedAgents()).slice(0, 2) : [];
|
|
136
|
+
const books = booksRendered
|
|
137
|
+
? publishedRuntime
|
|
138
|
+
? (await loadPublishedCollection(Astro.locals, 'books')).sort((a, b) => Number(a.data.order ?? 0) - Number(b.data.order ?? 0))
|
|
139
|
+
: await getPublishedBooks()
|
|
140
|
+
: [];
|
|
39
141
|
const ctaPrimaryHref = questionsRendered ? '/questions/' : objectivesRendered ? '/objectives/' : '/status/';
|
|
40
142
|
const ctaPrimaryLabel = questionsRendered ? 'Browse questions' : objectivesRendered ? 'Browse objectives' : 'View status';
|
|
41
143
|
const ctaSecondaryHref = booksRendered ? '/books/' : notesRendered ? '/notes/' : '/vision/';
|
|
@@ -62,7 +164,7 @@ const ctaSecondaryLabel = booksRendered ? 'Explore books' : notesRendered ? 'Rea
|
|
|
62
164
|
TreeSeed works best when contributors can understand the package, inspect the
|
|
63
165
|
tenant surface, and verify real workflows without reconstructing everything from
|
|
64
166
|
source code alone. This fixture keeps those paths visible by combining pages,
|
|
65
|
-
questions, objectives, books, agents, and forms in one generic working site.
|
|
167
|
+
questions, objectives, proposals, decisions, books, agents, and forms in one generic working site.
|
|
66
168
|
</p>
|
|
67
169
|
</div>
|
|
68
170
|
<div slot="actions">
|
|
@@ -72,7 +174,7 @@ const ctaSecondaryLabel = booksRendered ? 'Explore books' : notesRendered ? 'Rea
|
|
|
72
174
|
<div slot="aside" class="space-y-4">
|
|
73
175
|
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--site-blue-strong)]">Right now</p>
|
|
74
176
|
<ul class="space-y-4 text-base leading-8 text-[color:var(--site-text-muted)]">
|
|
75
|
-
<li>A full TreeSeed content surface with pages, notes, questions, objectives, people, agents, books, and docs.</li>
|
|
177
|
+
<li>A full TreeSeed content surface with pages, notes, questions, objectives, proposals, decisions, people, agents, books, and docs.</li>
|
|
76
178
|
<li>Package defaults exercised through a realistic tenant instead of isolated unit tests alone.</li>
|
|
77
179
|
<li>Forms, book exports, and navigation paths that participate in release verification.</li>
|
|
78
180
|
<li>A documentation-first example meant to stay easy to inspect and easy to maintain.</li>
|
|
@@ -117,10 +219,10 @@ const ctaSecondaryLabel = booksRendered ? 'Explore books' : notesRendered ? 'Rea
|
|
|
117
219
|
<div class="border border-[color:var(--site-border)] bg-[color:var(--site-surface)] p-6">
|
|
118
220
|
<h2 class="font-serif text-2xl text-[color:var(--site-text)]">Content commitments</h2>
|
|
119
221
|
<ul class="mt-4 space-y-3 text-base leading-8 text-[color:var(--site-text-muted)]">
|
|
120
|
-
<li>Questions and
|
|
222
|
+
<li>Questions, objectives, proposals, and decisions stay visible instead of disappearing into process notes.</li>
|
|
121
223
|
<li>Books and docs remain queryable content, not only navigation configuration.</li>
|
|
122
224
|
<li>People and agents are explicit contributors rather than invisible supporting actors.</li>
|
|
123
|
-
<li>Notes
|
|
225
|
+
<li>Notes can still capture evidence and rationale without replacing proposal and decision records.</li>
|
|
124
226
|
</ul>
|
|
125
227
|
</div>
|
|
126
228
|
<div class="border border-[color:var(--site-border)] bg-[color:var(--site-surface)] p-6">
|
|
@@ -145,7 +247,7 @@ const ctaSecondaryLabel = booksRendered ? 'Explore books' : notesRendered ? 'Rea
|
|
|
145
247
|
<div class="space-y-4 text-base leading-8 text-[color:var(--site-text-muted)]">
|
|
146
248
|
<p>
|
|
147
249
|
The current fixture demonstrates the full TreeSeed surface: pages, notes, questions,
|
|
148
|
-
objectives, people, agents, books, docs, and forms. That gives package changes a
|
|
250
|
+
objectives, proposals, decisions, people, agents, books, docs, and forms. That gives package changes a
|
|
149
251
|
tenant-level target instead of relying on isolated examples.
|
|
150
252
|
</p>
|
|
151
253
|
<p>
|
|
@@ -206,12 +308,12 @@ const ctaSecondaryLabel = booksRendered ? 'Explore books' : notesRendered ? 'Rea
|
|
|
206
308
|
</section>
|
|
207
309
|
)}
|
|
208
310
|
|
|
209
|
-
{(questionsRendered || objectivesRendered || peopleRendered || agentsRendered || booksRendered) && (
|
|
311
|
+
{(questionsRendered || objectivesRendered || proposalsRendered || decisionsRendered || peopleRendered || agentsRendered || booksRendered) && (
|
|
210
312
|
<section class="space-y-8 border-t border-[color:var(--site-border)] pt-10">
|
|
211
313
|
<SectionIntro
|
|
212
314
|
eyebrow="TreeSeed"
|
|
213
|
-
title="Questions, objectives, contributors, and books form one connected working surface"
|
|
214
|
-
description="The fixture shows how humans and agents can publish questions, anchor them to objectives, and
|
|
315
|
+
title="Questions, objectives, proposals, decisions, contributors, and books form one connected working surface"
|
|
316
|
+
description="The fixture shows how humans and agents can publish questions, anchor them to objectives, turn them into proposals, and record decisions without losing the surrounding context."
|
|
215
317
|
/>
|
|
216
318
|
<div class="grid gap-10 lg:grid-cols-2">
|
|
217
319
|
{questionsRendered && (
|
|
@@ -255,6 +357,48 @@ const ctaSecondaryLabel = booksRendered ? 'Explore books' : notesRendered ? 'Rea
|
|
|
255
357
|
</div>
|
|
256
358
|
)}
|
|
257
359
|
</div>
|
|
360
|
+
<div class="grid gap-10 lg:grid-cols-2">
|
|
361
|
+
{proposalsRendered && (
|
|
362
|
+
<div class="space-y-6">
|
|
363
|
+
<SectionIntro
|
|
364
|
+
eyebrow="Proposals"
|
|
365
|
+
title="Suggested change"
|
|
366
|
+
description="Proposals make the next suggested move explicit instead of leaving it scattered across notes or implied by workstream activity."
|
|
367
|
+
/>
|
|
368
|
+
<ChronicleList
|
|
369
|
+
items={proposals.map((proposal) => ({
|
|
370
|
+
href: `/proposals/${proposal.id}/`,
|
|
371
|
+
title: proposal.data.title,
|
|
372
|
+
summary: proposal.data.summary,
|
|
373
|
+
status: proposal.data.status,
|
|
374
|
+
date: proposal.data.date,
|
|
375
|
+
meta: proposalContributors.get(proposal.id)?.data.name,
|
|
376
|
+
tags: proposal.data.tags,
|
|
377
|
+
}))}
|
|
378
|
+
/>
|
|
379
|
+
</div>
|
|
380
|
+
)}
|
|
381
|
+
{decisionsRendered && (
|
|
382
|
+
<div class="space-y-6">
|
|
383
|
+
<SectionIntro
|
|
384
|
+
eyebrow="Decisions"
|
|
385
|
+
title="Chosen path"
|
|
386
|
+
description="Decisions record what was actually accepted, deferred, rejected, or superseded so the site can accumulate institutional memory instead of only discussion."
|
|
387
|
+
/>
|
|
388
|
+
<ChronicleList
|
|
389
|
+
items={decisions.map((decision) => ({
|
|
390
|
+
href: `/decisions/${decision.id}/`,
|
|
391
|
+
title: decision.data.title,
|
|
392
|
+
summary: decision.data.summary,
|
|
393
|
+
status: decision.data.status,
|
|
394
|
+
date: decision.data.date,
|
|
395
|
+
meta: decisionContributors.get(decision.id)?.data.name,
|
|
396
|
+
tags: decision.data.tags,
|
|
397
|
+
}))}
|
|
398
|
+
/>
|
|
399
|
+
</div>
|
|
400
|
+
)}
|
|
401
|
+
</div>
|
|
258
402
|
<div class="grid gap-10 lg:grid-cols-2">
|
|
259
403
|
{(peopleRendered || agentsRendered) && (
|
|
260
404
|
<div class="space-y-6">
|
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection, render } from 'astro:content';
|
|
3
3
|
import NoteLayout from '../../layouts/NoteLayout.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 notes = publishedRuntime ? [] : await getCollection('notes', ({ data }) => !data.draft);
|
|
13
|
+
const localNote = publishedRuntime ? null : notes.find((candidate) => candidate.id === slug) ?? null;
|
|
14
|
+
const publishedNote = publishedRuntime ? await loadPublishedEntry(Astro.locals, 'notes', slug) : null;
|
|
15
|
+
const note = publishedRuntime ? publishedNote?.entry ?? null : localNote;
|
|
11
16
|
if (!note) {
|
|
12
17
|
Astro.response.status = 404;
|
|
13
18
|
}
|
|
14
|
-
const rendered =
|
|
19
|
+
const rendered = !publishedRuntime && localNote ? await render(localNote) : null;
|
|
15
20
|
const Content = rendered?.Content ?? null;
|
|
16
21
|
---
|
|
17
22
|
|
|
18
23
|
{
|
|
19
|
-
!note || !Content ? (
|
|
24
|
+
!note || (!Content && !publishedNote?.html) ? (
|
|
20
25
|
<RouteNotFound title="Note not found" description="The requested note could not be found in this Treeseed." currentPath="/notes/" />
|
|
21
26
|
) : (
|
|
22
27
|
<NoteLayout note={note.data}>
|
|
23
|
-
<Content />
|
|
28
|
+
{publishedRuntime ? <PublishedContentBody html={publishedNote?.html ?? ''} /> : <Content />}
|
|
24
29
|
</NoteLayout>
|
|
25
30
|
)
|
|
26
31
|
}
|
|
@@ -3,10 +3,13 @@ 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 NotesList from '../../components/site/NotesList.astro';
|
|
6
|
+
import { isPublishedRuntimeContentMode, loadPublishedCollection } from '../../utils/site-content-runtime';
|
|
6
7
|
|
|
7
|
-
const notes = (
|
|
8
|
-
(a, b) => b.data.date.valueOf() - a.data.date.valueOf()
|
|
9
|
-
)
|
|
8
|
+
const notes = isPublishedRuntimeContentMode()
|
|
9
|
+
? (await loadPublishedCollection(Astro.locals, 'notes')).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
|
10
|
+
: (await getCollection('notes', ({ data }) => !data.draft)).sort(
|
|
11
|
+
(a, b) => b.data.date.valueOf() - a.data.date.valueOf(),
|
|
12
|
+
);
|
|
10
13
|
---
|
|
11
14
|
|
|
12
15
|
<MainLayout title="Notes" description="Public working notes from the TreeSeed fixture site." currentPath="/notes/">
|
|
@@ -2,25 +2,43 @@
|
|
|
2
2
|
import { getCollection, render } from 'astro:content';
|
|
3
3
|
import AuthoredEntryLayout from '../../layouts/AuthoredEntryLayout.astro';
|
|
4
4
|
import { resolveContributor, resolveReferences } from '../../utils/hub-content';
|
|
5
|
+
import PublishedContentBody from '../../components/site/PublishedContentBody.astro';
|
|
5
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';
|
|
6
14
|
|
|
7
15
|
export const prerender = false;
|
|
8
16
|
|
|
9
17
|
const slug = String(Astro.params.slug ?? '');
|
|
10
|
-
const
|
|
11
|
-
const
|
|
18
|
+
const publishedRuntime = isPublishedRuntimeContentMode();
|
|
19
|
+
const objectives = publishedRuntime ? [] : await getCollection('objectives', ({ data }) => !data.draft);
|
|
20
|
+
const localObjective = publishedRuntime ? null : objectives.find((candidate) => candidate.id === slug) ?? null;
|
|
21
|
+
const publishedObjective = publishedRuntime ? await loadPublishedEntry(Astro.locals, 'objectives', slug) : null;
|
|
22
|
+
const objective = publishedRuntime ? publishedObjective?.entry ?? null : localObjective;
|
|
23
|
+
const metadata = publishedRuntime ? metadataFromPublishedContent(publishedObjective?.content) : null;
|
|
12
24
|
if (!objective) {
|
|
13
25
|
Astro.response.status = 404;
|
|
14
26
|
}
|
|
15
|
-
const rendered =
|
|
27
|
+
const rendered = !publishedRuntime && localObjective ? await render(localObjective) : null;
|
|
16
28
|
const Content = rendered?.Content ?? null;
|
|
17
|
-
const contributor =
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
const contributor = publishedRuntime
|
|
30
|
+
? await resolvePublishedContributor(Astro.locals, metadata?.primaryContributor)
|
|
31
|
+
: objective ? await resolveContributor(objective.data.primaryContributor) : null;
|
|
32
|
+
const relatedQuestions = publishedRuntime
|
|
33
|
+
? await resolvePublishedReferences(Astro.locals, 'questions', metadata?.relatedQuestions)
|
|
34
|
+
: objective ? await resolveReferences(objective.data.relatedQuestions) : [];
|
|
35
|
+
const relatedBooks = publishedRuntime
|
|
36
|
+
? await resolvePublishedReferences(Astro.locals, 'books', metadata?.relatedBooks)
|
|
37
|
+
: objective ? await resolveReferences(objective.data.relatedBooks) : [];
|
|
20
38
|
---
|
|
21
39
|
|
|
22
40
|
{
|
|
23
|
-
!objective || !Content ? (
|
|
41
|
+
!objective || (!Content && !publishedObjective?.html) ? (
|
|
24
42
|
<RouteNotFound title="Objective not found" description="The requested objective could not be found in this Treeseed." currentPath="/objectives/" />
|
|
25
43
|
) : (
|
|
26
44
|
<AuthoredEntryLayout
|
|
@@ -28,11 +46,11 @@ const relatedBooks = objective ? await resolveReferences(objective.data.relatedB
|
|
|
28
46
|
currentPath="/objectives/"
|
|
29
47
|
contributor={contributor}
|
|
30
48
|
metaLabel="Time horizon"
|
|
31
|
-
metaValue={objective.data.timeHorizon}
|
|
49
|
+
metaValue={String(objective.data.timeHorizon ?? '')}
|
|
32
50
|
relatedQuestions={relatedQuestions}
|
|
33
51
|
relatedBooks={relatedBooks}
|
|
34
52
|
>
|
|
35
|
-
<Content />
|
|
53
|
+
{publishedRuntime ? <PublishedContentBody html={publishedObjective?.html ?? ''} /> : <Content />}
|
|
36
54
|
</AuthoredEntryLayout>
|
|
37
55
|
)
|
|
38
56
|
}
|
|
@@ -3,9 +3,26 @@ import MainLayout from '../../layouts/MainLayout.astro';
|
|
|
3
3
|
import SectionIntro from '../../components/site/SectionIntro.astro';
|
|
4
4
|
import ChronicleList from '../../components/site/ChronicleList.astro';
|
|
5
5
|
import { getPublishedObjectives, resolveContributorsForEntries } from '../../utils/hub-content';
|
|
6
|
+
import { isPublishedRuntimeContentMode, loadPublishedCollection, resolvePublishedContributor, metadataFromPublishedContent, loadPublishedEntry } from '../../utils/site-content-runtime';
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
-
const
|
|
8
|
+
const publishedRuntime = isPublishedRuntimeContentMode();
|
|
9
|
+
const objectives = publishedRuntime
|
|
10
|
+
? (await loadPublishedCollection(Astro.locals, 'objectives')).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
|
11
|
+
: await getPublishedObjectives();
|
|
12
|
+
const contributors = publishedRuntime
|
|
13
|
+
? new Map(
|
|
14
|
+
await Promise.all(
|
|
15
|
+
objectives.map(async (objective) => {
|
|
16
|
+
const detail = await loadPublishedEntry(Astro.locals, 'objectives', objective.id);
|
|
17
|
+
const contributor = await resolvePublishedContributor(
|
|
18
|
+
Astro.locals,
|
|
19
|
+
metadataFromPublishedContent(detail?.content)?.primaryContributor,
|
|
20
|
+
);
|
|
21
|
+
return [objective.id, contributor ?? null] as const;
|
|
22
|
+
}),
|
|
23
|
+
),
|
|
24
|
+
)
|
|
25
|
+
: await resolveContributorsForEntries(objectives);
|
|
9
26
|
---
|
|
10
27
|
|
|
11
28
|
<MainLayout title="Objectives" description="Strategic objectives guiding the TreeSeed working site." currentPath="/objectives/">
|
|
@@ -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 people = publishedRuntime ? [] : await getCollection('people');
|
|
14
|
+
const localPerson = publishedRuntime ? null : people.find((candidate) => candidate.id === slug) ?? null;
|
|
15
|
+
const publishedPerson = publishedRuntime ? await loadPublishedEntry(Astro.locals, 'people', slug) : null;
|
|
16
|
+
const person = publishedRuntime ? publishedPerson?.entry ?? null : localPerson;
|
|
17
|
+
const metadata = publishedRuntime ? metadataFromPublishedContent(publishedPerson?.content) : null;
|
|
12
18
|
if (!person) {
|
|
13
19
|
Astro.response.status = 404;
|
|
14
20
|
}
|
|
15
|
-
const rendered =
|
|
21
|
+
const rendered = !publishedRuntime && localPerson ? await render(localPerson) : 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
|
+
: person ? await resolveReferences(person.data.relatedQuestions) : [];
|
|
26
|
+
const relatedObjectives = publishedRuntime
|
|
27
|
+
? await resolvePublishedReferences(Astro.locals, 'objectives', metadata?.relatedObjectives)
|
|
28
|
+
: person ? await resolveReferences(person.data.relatedObjectives) : [];
|
|
19
29
|
---
|
|
20
30
|
|
|
21
31
|
{
|
|
22
|
-
!person || !Content ? (
|
|
32
|
+
!person || (!Content && !publishedPerson?.html) ? (
|
|
23
33
|
<RouteNotFound title="Profile not found" description="The requested person profile could not be found in this Treeseed." currentPath="/people/" />
|
|
24
34
|
) : (
|
|
25
35
|
<ProfileLayout
|
|
@@ -30,7 +40,7 @@ const relatedObjectives = person ? await resolveReferences(person.data.relatedOb
|
|
|
30
40
|
relatedQuestions={relatedQuestions}
|
|
31
41
|
relatedObjectives={relatedObjectives}
|
|
32
42
|
>
|
|
33
|
-
<Content />
|
|
43
|
+
{publishedRuntime ? <PublishedContentBody html={publishedPerson?.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 people = await getCollection('people');
|
|
8
|
+
const people = isPublishedRuntimeContentMode() ? await loadPublishedCollection(Astro.locals, 'people') : await getCollection('people');
|
|
8
9
|
---
|
|
9
10
|
|
|
10
11
|
<MainLayout title="People" description="Human contributors participating in the TreeSeed working site." currentPath="/people/">
|
|
@@ -0,0 +1,72 @@
|
|
|
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 proposals = publishedRuntime ? [] : await getCollection('proposals', ({ data }) => !data.draft);
|
|
20
|
+
const localProposal = publishedRuntime ? null : proposals.find((candidate) => candidate.id === slug) ?? null;
|
|
21
|
+
const publishedProposal = publishedRuntime ? await loadPublishedEntry(Astro.locals, 'proposals', slug) : null;
|
|
22
|
+
const proposal = publishedRuntime ? publishedProposal?.entry ?? null : localProposal;
|
|
23
|
+
const metadata = publishedRuntime ? metadataFromPublishedContent(publishedProposal?.content) : null;
|
|
24
|
+
if (!proposal) {
|
|
25
|
+
Astro.response.status = 404;
|
|
26
|
+
}
|
|
27
|
+
const rendered = !publishedRuntime && localProposal ? await render(localProposal) : null;
|
|
28
|
+
const Content = rendered?.Content ?? null;
|
|
29
|
+
const contributor = publishedRuntime
|
|
30
|
+
? await resolvePublishedContributor(Astro.locals, metadata?.primaryContributor)
|
|
31
|
+
: proposal ? await resolveContributor(proposal.data.primaryContributor) : null;
|
|
32
|
+
const relatedObjectives = publishedRuntime
|
|
33
|
+
? await resolvePublishedReferences(Astro.locals, 'objectives', metadata?.relatedObjectives)
|
|
34
|
+
: proposal ? await resolveReferences(proposal.data.relatedObjectives) : [];
|
|
35
|
+
const relatedQuestions = publishedRuntime
|
|
36
|
+
? await resolvePublishedReferences(Astro.locals, 'questions', metadata?.relatedQuestions)
|
|
37
|
+
: proposal ? await resolveReferences(proposal.data.relatedQuestions) : [];
|
|
38
|
+
const relatedNotes = publishedRuntime
|
|
39
|
+
? await resolvePublishedReferences(Astro.locals, 'notes', metadata?.relatedNotes)
|
|
40
|
+
: proposal ? await resolveReferences(proposal.data.relatedNotes) : [];
|
|
41
|
+
const relatedBooks = publishedRuntime
|
|
42
|
+
? await resolvePublishedReferences(Astro.locals, 'books', metadata?.relatedBooks)
|
|
43
|
+
: proposal ? await resolveReferences(proposal.data.relatedBooks) : [];
|
|
44
|
+
const relatedDecisions = publishedRuntime
|
|
45
|
+
? await resolvePublishedReferences(Astro.locals, 'decisions', metadata?.decision ? [String(metadata.decision)] : [])
|
|
46
|
+
: proposal?.data.decision ? await resolveReferences([proposal.data.decision]) : [];
|
|
47
|
+
const supersededProposals = publishedRuntime
|
|
48
|
+
? await resolvePublishedReferences(Astro.locals, 'proposals', metadata?.supersedes)
|
|
49
|
+
: proposal ? await resolveReferences(proposal.data.supersedes) : [];
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
{
|
|
53
|
+
!proposal || (!Content && !publishedProposal?.html) ? (
|
|
54
|
+
<RouteNotFound title="Proposal not found" description="The requested proposal could not be found in this Treeseed." currentPath="/proposals/" />
|
|
55
|
+
) : (
|
|
56
|
+
<AuthoredEntryLayout
|
|
57
|
+
entry={proposal.data}
|
|
58
|
+
currentPath="/proposals/"
|
|
59
|
+
contributor={contributor}
|
|
60
|
+
metaLabel="Proposal type"
|
|
61
|
+
metaValue={String(proposal.data.proposalType ?? '')}
|
|
62
|
+
relatedObjectives={relatedObjectives}
|
|
63
|
+
relatedQuestions={relatedQuestions}
|
|
64
|
+
relatedNotes={relatedNotes}
|
|
65
|
+
relatedDecisions={relatedDecisions}
|
|
66
|
+
relatedProposals={supersededProposals}
|
|
67
|
+
relatedBooks={relatedBooks}
|
|
68
|
+
>
|
|
69
|
+
{publishedRuntime ? <PublishedContentBody html={publishedProposal?.html ?? ''} /> : <Content />}
|
|
70
|
+
</AuthoredEntryLayout>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
@@ -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 { getPublishedProposals, resolveContributorsForEntries } from '../../utils/hub-content';
|
|
6
|
+
import { isPublishedRuntimeContentMode, loadPublishedCollection, resolvePublishedContributor, metadataFromPublishedContent, loadPublishedEntry } from '../../utils/site-content-runtime';
|
|
7
|
+
|
|
8
|
+
const publishedRuntime = isPublishedRuntimeContentMode();
|
|
9
|
+
const proposals = publishedRuntime
|
|
10
|
+
? (await loadPublishedCollection(Astro.locals, 'proposals')).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
|
11
|
+
: await getPublishedProposals();
|
|
12
|
+
const contributors = publishedRuntime
|
|
13
|
+
? new Map(
|
|
14
|
+
await Promise.all(
|
|
15
|
+
proposals.map(async (proposal) => {
|
|
16
|
+
const detail = await loadPublishedEntry(Astro.locals, 'proposals', proposal.id);
|
|
17
|
+
const contributor = await resolvePublishedContributor(
|
|
18
|
+
Astro.locals,
|
|
19
|
+
metadataFromPublishedContent(detail?.content)?.primaryContributor,
|
|
20
|
+
);
|
|
21
|
+
return [proposal.id, contributor ?? null] as const;
|
|
22
|
+
}),
|
|
23
|
+
),
|
|
24
|
+
)
|
|
25
|
+
: await resolveContributorsForEntries(proposals);
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
<MainLayout title="Proposals" description="Proposals that move Treeseed from context to an explicit suggested change." currentPath="/proposals/">
|
|
29
|
+
<div class="space-y-10">
|
|
30
|
+
<SectionIntro
|
|
31
|
+
eyebrow="Proposals"
|
|
32
|
+
title="Suggested changes made explicit"
|
|
33
|
+
description="Proposals are where TreeSeed turns observations and open questions into a concrete suggested change, policy, implementation, or research move."
|
|
34
|
+
/>
|
|
35
|
+
<ChronicleList
|
|
36
|
+
items={proposals.map((proposal) => ({
|
|
37
|
+
href: `/proposals/${proposal.id}/`,
|
|
38
|
+
title: proposal.data.title,
|
|
39
|
+
summary: proposal.data.summary,
|
|
40
|
+
status: proposal.data.status,
|
|
41
|
+
date: proposal.data.date,
|
|
42
|
+
meta: contributors.get(proposal.id)?.data.name,
|
|
43
|
+
tags: proposal.data.tags,
|
|
44
|
+
}))}
|
|
45
|
+
/>
|
|
46
|
+
</div>
|
|
47
|
+
</MainLayout>
|
|
@@ -2,25 +2,43 @@
|
|
|
2
2
|
import { getCollection, render } from 'astro:content';
|
|
3
3
|
import AuthoredEntryLayout from '../../layouts/AuthoredEntryLayout.astro';
|
|
4
4
|
import { resolveContributor, resolveReferences } from '../../utils/hub-content';
|
|
5
|
+
import PublishedContentBody from '../../components/site/PublishedContentBody.astro';
|
|
5
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';
|
|
6
14
|
|
|
7
15
|
export const prerender = false;
|
|
8
16
|
|
|
9
17
|
const slug = String(Astro.params.slug ?? '');
|
|
10
|
-
const
|
|
11
|
-
const
|
|
18
|
+
const publishedRuntime = isPublishedRuntimeContentMode();
|
|
19
|
+
const questions = publishedRuntime ? [] : await getCollection('questions', ({ data }) => !data.draft);
|
|
20
|
+
const localQuestion = publishedRuntime ? null : questions.find((candidate) => candidate.id === slug) ?? null;
|
|
21
|
+
const publishedQuestion = publishedRuntime ? await loadPublishedEntry(Astro.locals, 'questions', slug) : null;
|
|
22
|
+
const question = publishedRuntime ? publishedQuestion?.entry ?? null : localQuestion;
|
|
23
|
+
const metadata = publishedRuntime ? metadataFromPublishedContent(publishedQuestion?.content) : null;
|
|
12
24
|
if (!question) {
|
|
13
25
|
Astro.response.status = 404;
|
|
14
26
|
}
|
|
15
|
-
const rendered =
|
|
27
|
+
const rendered = !publishedRuntime && localQuestion ? await render(localQuestion) : null;
|
|
16
28
|
const Content = rendered?.Content ?? null;
|
|
17
|
-
const contributor =
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
const contributor = publishedRuntime
|
|
30
|
+
? await resolvePublishedContributor(Astro.locals, metadata?.primaryContributor)
|
|
31
|
+
: question ? await resolveContributor(question.data.primaryContributor) : null;
|
|
32
|
+
const relatedObjectives = publishedRuntime
|
|
33
|
+
? await resolvePublishedReferences(Astro.locals, 'objectives', metadata?.relatedObjectives)
|
|
34
|
+
: question ? await resolveReferences(question.data.relatedObjectives) : [];
|
|
35
|
+
const relatedBooks = publishedRuntime
|
|
36
|
+
? await resolvePublishedReferences(Astro.locals, 'books', metadata?.relatedBooks)
|
|
37
|
+
: question ? await resolveReferences(question.data.relatedBooks) : [];
|
|
20
38
|
---
|
|
21
39
|
|
|
22
40
|
{
|
|
23
|
-
!question || !Content ? (
|
|
41
|
+
!question || (!Content && !publishedQuestion?.html) ? (
|
|
24
42
|
<RouteNotFound title="Question not found" description="The requested question could not be found in this Treeseed." currentPath="/questions/" />
|
|
25
43
|
) : (
|
|
26
44
|
<AuthoredEntryLayout
|
|
@@ -28,11 +46,11 @@ const relatedBooks = question ? await resolveReferences(question.data.relatedBoo
|
|
|
28
46
|
currentPath="/questions/"
|
|
29
47
|
contributor={contributor}
|
|
30
48
|
metaLabel="Question type"
|
|
31
|
-
metaValue={question.data.questionType}
|
|
49
|
+
metaValue={String(question.data.questionType ?? '')}
|
|
32
50
|
relatedObjectives={relatedObjectives}
|
|
33
51
|
relatedBooks={relatedBooks}
|
|
34
52
|
>
|
|
35
|
-
<Content />
|
|
53
|
+
{publishedRuntime ? <PublishedContentBody html={publishedQuestion?.html ?? ''} /> : <Content />}
|
|
36
54
|
</AuthoredEntryLayout>
|
|
37
55
|
)
|
|
38
56
|
}
|