@treeseed/core 0.8.19 → 0.9.4

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.
@@ -5,9 +5,11 @@ import '../../../styles/ui.css';
5
5
  import '../../../styles/forms.css';
6
6
  import '../../../styles/app-shell.css';
7
7
  import ThemeScript from '../theme/ThemeScript.astro';
8
+ import ThemeMenu from '../theme/ThemeMenu.astro';
8
9
  import RailNav from './RailNav.astro';
9
10
  import BottomNav from './BottomNav.astro';
10
11
  import TopBar from './TopBar.astro';
12
+ import ShellIconLink from './ShellIconLink.astro';
11
13
  import Button from '../forms/Button.astro';
12
14
  import DevWatchReload from '../../DevWatchReload.astro';
13
15
  import type { ButtonAction } from '../types.js';
@@ -64,11 +66,13 @@ const {
64
66
  <a class="ts-skip-link" href="#main-content">Skip to content</a>
65
67
  <div class="ts-app-shell">
66
68
  <aside class="ts-app-shell__rail">
67
- <TopBar brand={brand} />
68
- <div class="ts-app-shell__rail-context">
69
- <slot name="railContext" />
69
+ <div class="ts-app-shell__rail-scroll">
70
+ <TopBar brand={brand} />
71
+ <div class="ts-app-shell__rail-context">
72
+ <slot name="railContext" />
73
+ </div>
74
+ <RailNav items={navItems} currentPath={currentPath} />
70
75
  </div>
71
- <RailNav items={navItems} currentPath={currentPath} />
72
76
  {quickActions.length > 0 ? (
73
77
  <div class="ts-app-shell__quick-actions">
74
78
  <p class="ts-app-shell__eyebrow">Quick actions</p>
@@ -91,6 +95,10 @@ const {
91
95
  </aside>
92
96
  <main class="ts-app-shell__main" id="main-content">
93
97
  <TopBar brand={brand} class="ts-app-shell__mobile-top">
98
+ <Fragment slot="actions">
99
+ <ThemeMenu selectedScheme={appearance.scheme} selectedMode={appearance.mode} />
100
+ <ShellIconLink href="/" label="Book home" icon="book" />
101
+ </Fragment>
94
102
  </TopBar>
95
103
  <header class="ts-app-shell__header">
96
104
  <div class="ts-app-shell__title">
@@ -98,6 +106,10 @@ const {
98
106
  <p>{description}</p>
99
107
  </div>
100
108
  <div class="ts-app-shell__header-actions">
109
+ <div class="ts-shell-utility-actions">
110
+ <ThemeMenu selectedScheme={appearance.scheme} selectedMode={appearance.mode} />
111
+ <ShellIconLink href="/" label="Book home" icon="book" />
112
+ </div>
101
113
  <slot name="headerAction" />
102
114
  </div>
103
115
  </header>
@@ -19,10 +19,17 @@ const {
19
19
  class: className,
20
20
  } = Astro.props as Props;
21
21
 
22
+ function normalizePath(path: string) {
23
+ if (path.length <= 1) return path;
24
+ return path.replace(/\/+$/u, '');
25
+ }
26
+
22
27
  function isCurrentPath(href: string) {
23
- if (href === '/') return currentPath === '/';
24
- if (href.endsWith('/')) return currentPath === href || currentPath.startsWith(href);
25
- return currentPath === href || currentPath.startsWith(`${href}/`);
28
+ const current = normalizePath(currentPath);
29
+ const target = normalizePath(href);
30
+ if (target === '/') return current === '/';
31
+ if (target === '/app') return current === '/app';
32
+ return current === target || current.startsWith(`${target}/`);
26
33
  }
27
34
  ---
28
35
 
@@ -19,10 +19,17 @@ const {
19
19
  class: className,
20
20
  } = Astro.props as Props;
21
21
 
22
+ function normalizePath(path: string) {
23
+ if (path.length <= 1) return path;
24
+ return path.replace(/\/+$/u, '');
25
+ }
26
+
22
27
  function isCurrentPath(href: string) {
23
- if (href === '/') return currentPath === '/';
24
- if (href.endsWith('/')) return currentPath === href || currentPath.startsWith(href);
25
- return currentPath === href || currentPath.startsWith(`${href}/`);
28
+ const current = normalizePath(currentPath);
29
+ const target = normalizePath(href);
30
+ if (target === '/') return current === '/';
31
+ if (target === '/app') return current === '/app';
32
+ return current === target || current.startsWith(`${target}/`);
26
33
  }
27
34
  ---
28
35
 
@@ -0,0 +1,30 @@
1
+ ---
2
+ interface Props {
3
+ href: string;
4
+ label: string;
5
+ icon: 'book' | 'manager';
6
+ }
7
+
8
+ const { href, label, icon } = Astro.props as Props;
9
+ ---
10
+
11
+ <a
12
+ href={href}
13
+ aria-label={label}
14
+ title={label}
15
+ class="ts-public-shell__icon-link ts-public-shell__icon-link--stroke"
16
+ >
17
+ {icon === 'manager' ? (
18
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
19
+ <path d="M12 15.25a3.25 3.25 0 1 0 0-6.5 3.25 3.25 0 0 0 0 6.5Z" />
20
+ <path d="M19.43 12.98c.04-.32.07-.65.07-.98s-.02-.66-.07-.98l2.05-1.6-2-3.46-2.42.98a7.65 7.65 0 0 0-1.7-.98L15 3.38h-4l-.36 2.58c-.6.24-1.17.57-1.7.98l-2.42-.98-2 3.46 2.05 1.6c-.04.32-.07.65-.07.98s.02.66.07.98l-2.05 1.6 2 3.46 2.42-.98c.52.41 1.09.74 1.7.98l.36 2.58h4l.36-2.58c.6-.24 1.17-.57 1.7-.98l2.42.98 2-3.46-2.05-1.6Z" />
21
+ </svg>
22
+ ) : (
23
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
24
+ <path d="M4.75 5.75A2.75 2.75 0 0 1 7.5 3h11.75v16.25H7.5a2.75 2.75 0 0 0-2.75 2.75V5.75Z" />
25
+ <path d="M7.5 19.25h11.75" />
26
+ <path d="M8.25 7.25h7.5" />
27
+ <path d="M8.25 10.75h6" />
28
+ </svg>
29
+ )}
30
+ </a>
@@ -5,6 +5,7 @@ export declare function createTreeseedTenantCollections(manifestPath?: string):
5
5
  objectives: any;
6
6
  people: any;
7
7
  agents: any;
8
+ agent_tests?: any;
8
9
  books: any;
9
10
  docs: any;
10
11
  workdays?: any;
package/dist/content.js CHANGED
@@ -2,6 +2,7 @@ import { defineCollection, reference } from "astro:content";
2
2
  import { z } from "astro/zod";
3
3
  import { glob } from "astro/loaders";
4
4
  import { existsSync, readdirSync } from "node:fs";
5
+ import { dirname, resolve } from "node:path";
5
6
  import { AGENT_CLI_ALLOW_TOOLS } from "@treeseed/sdk/types/agents";
6
7
  import { loadTreeseedPluginRuntime } from "@treeseed/sdk/platform/plugins";
7
8
  import { loadTreeseedDeployConfig } from "@treeseed/sdk/platform/deploy-config";
@@ -23,7 +24,7 @@ const statusValues = ["live", "in progress", "exploratory", "planned", "speculat
23
24
  const pageLayoutValues = ["article", "bridge"];
24
25
  const questionTypeValues = ["research", "implementation", "strategy", "evaluation"];
25
26
  const proposalTypeValues = ["strategy", "policy", "implementation", "research"];
26
- const decisionTypeValues = ["approved", "rejected", "deferred", "superseded"];
27
+ const decisionTypeValues = ["approved", "rejected", "deferred", "request_changes", "superseded"];
27
28
  const timeHorizonValues = ["near-term", "mid-term", "long-term"];
28
29
  const runtimeStatusValues = ["active", "experimental", "dormant"];
29
30
  const agentTriggerTypeValues = ["schedule", "message", "follow", "startup"];
@@ -362,6 +363,15 @@ function createTreeseedCollections(tenantConfig, { docsLoader, docsSchema }) {
362
363
  outputs: agentOutputSchema.default({}),
363
364
  governance: agentGovernanceSchema.optional()
364
365
  }));
366
+ const agentTestSchema = z.object({
367
+ id: z.string(),
368
+ agent: z.string(),
369
+ kind: z.enum(["spec", "handler", "message_chain", "manager_worker", "workday", "api", "ui"]),
370
+ fixture: z.string().optional(),
371
+ trigger: z.record(z.any()).default({}),
372
+ expect: z.record(z.any()).default({}),
373
+ tags: z.array(z.string()).default([])
374
+ });
365
375
  const bookSchema = z.preprocess((value) => preprocessAliasedRecord(bookFieldAliases, value), z.object({
366
376
  order: z.number().int().nonnegative(),
367
377
  slug: z.string(),
@@ -450,7 +460,7 @@ function createTreeseedCollections(tenantConfig, { docsLoader, docsSchema }) {
450
460
  completedAt: z.coerce.date().optional(),
451
461
  lastErrorCode: z.string().nullable().optional(),
452
462
  lastErrorMessage: z.string().nullable().optional(),
453
- lastEventKind: z.string().optional(),
463
+ lastEventKind: z.string().nullable().optional(),
454
464
  outputCount: z.number().int().optional(),
455
465
  changedFiles: z.array(z.string()).default([])
456
466
  });
@@ -528,6 +538,13 @@ function createTreeseedCollections(tenantConfig, { docsLoader, docsSchema }) {
528
538
  schema: docsCollectionProvider.schema
529
539
  })
530
540
  };
541
+ const agentTestsRoot = resolve(dirname(tenantConfig.content.agents), "agent-tests");
542
+ if (existsSync(agentTestsRoot)) {
543
+ collections.agent_tests = defineCollection({
544
+ loader: optionalMarkdownGlob(agentTestsRoot),
545
+ schema: agentTestSchema
546
+ });
547
+ }
531
548
  if (tenantConfig.content.workdays) {
532
549
  collections.workdays = defineCollection({
533
550
  loader: optionalMarkdownGlob(tenantConfig.content.workdays),
package/dist/dev.d.ts CHANGED
@@ -32,11 +32,13 @@ export type TreeseedIntegratedDevOptions = {
32
32
  webPort?: number;
33
33
  apiHost?: string;
34
34
  apiPort?: number;
35
+ webRuntime?: TreeseedLocalRuntimeMode;
35
36
  setupMode?: TreeseedIntegratedDevSetupMode;
36
37
  feedbackMode?: TreeseedIntegratedDevFeedbackMode;
37
38
  openMode?: TreeseedIntegratedDevOpenMode;
38
39
  plan?: boolean;
39
40
  reset?: boolean;
41
+ force?: boolean;
40
42
  json?: boolean;
41
43
  includeServices?: boolean;
42
44
  projectId?: string;
@@ -97,6 +99,7 @@ export type TreeseedIntegratedDevPlan = {
97
99
  readyChecks: TreeseedIntegratedDevReadinessCheck[];
98
100
  watchEntries: TreeseedIntegratedDevWatchEntry[];
99
101
  commands: TreeseedIntegratedDevCommand[];
102
+ logPath: string;
100
103
  localRuntimes: Record<string, TreeseedLocalRuntimeSelection>;
101
104
  restartPolicy: {
102
105
  initialBackoffMs: number;
@@ -127,6 +130,13 @@ type TreeseedIntegratedDevDependencies = {
127
130
  startWatch: WatchStarter;
128
131
  removePath: (path: string) => void;
129
132
  stopMailpitContainers: () => boolean;
133
+ inspectPortOwners: (ports: readonly number[]) => TreeseedDevPortOwner[];
134
+ };
135
+ export type TreeseedDevPortOwner = {
136
+ port: number;
137
+ pid: number | null;
138
+ processName?: string;
139
+ detail: string;
130
140
  };
131
141
  export declare function createTreeseedIntegratedDevResetPlan(options: {
132
142
  tenantRoot: string;