@owlmeans/create-app 0.1.18-rc.13 → 0.1.18-rc.15
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/README.md +37 -1
- package/build/args.d.ts +8 -0
- package/build/args.d.ts.map +1 -1
- package/build/args.js +60 -6
- package/build/args.js.map +1 -1
- package/build/index.d.ts +4 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/naming.d.ts +11 -0
- package/build/naming.d.ts.map +1 -0
- package/build/naming.js +18 -0
- package/build/naming.js.map +1 -0
- package/build/run.d.ts.map +1 -1
- package/build/run.js +19 -13
- package/build/run.js.map +1 -1
- package/build/scaffold.d.ts +21 -0
- package/build/scaffold.d.ts.map +1 -0
- package/build/scaffold.js +18 -0
- package/build/scaffold.js.map +1 -0
- package/build/template.d.ts +19 -3
- package/build/template.d.ts.map +1 -1
- package/build/template.js +52 -12
- package/build/template.js.map +1 -1
- package/package.json +4 -3
- package/template/AGENTS.md +20 -1
- package/template/README.bare.md +57 -0
- package/template/README.md +15 -8
- package/template/_agents/scripts/link-skills.sh +310 -15
- package/template/_agents/skills/agent-memory/SKILL.md +12 -11
- package/template/_agents/skills/getting-started/SKILL.md +66 -19
- package/template/_agents/skills/memory-promotion/SKILL.md +10 -4
- package/template/_agents/skills/memory-recompact/SKILL.md +15 -14
- package/template/_agents/skills/reuse-code/SKILL.md +36 -8
- package/template/_agents/skills/self-education/SKILL.md +19 -5
- package/template/_agents/skills/skill-authoring/SKILL.md +53 -11
- package/template/_bare.json +23 -0
- package/template/_gitignore +3 -0
- package/template/bunfig.toml +2 -0
- package/template/package.json +2 -1
- package/template/sources/api/src/app/session/list.ts +6 -4
- package/template/sources/api/src/app/session/remove.ts +1 -1
- package/template/sources/api/src/context.bare.ts +11 -0
- package/template/sources/api/src/context.ts +0 -4
- package/template/sources/api/src/entrypoints.bare.ts +6 -0
- package/template/sources/api/src/entrypoints.ts +11 -0
- package/template/sources/api/src/index.ts +2 -2
- package/template/sources/api/src/types.bare.ts +5 -0
- package/template/sources/common/src/consts.bare.ts +8 -0
- package/template/sources/common/src/entrypoints.bare.ts +8 -0
- package/template/sources/common/src/{modules.ts → entrypoints.ts} +1 -1
- package/template/sources/common/src/index.bare.ts +3 -0
- package/template/sources/common/src/index.ts +1 -1
- package/template/sources/web/index.html +3 -1
- package/template/sources/web/src/context.bare.ts +13 -0
- package/template/sources/web/src/context.ts +0 -4
- package/template/sources/web/src/entrypoints.bare.ts +14 -0
- package/template/sources/web/src/entrypoints.ts +22 -0
- package/template/sources/web/src/index.tsx +2 -2
- package/template/sources/web/src/nav.bare.ts +21 -0
- package/template/sources/web/src/screens/home.bare.tsx +17 -0
- package/template/sources/web/src/screens/session.tsx +7 -7
- package/template/sources/web/src/vite-env.d.ts +1 -0
- package/template/sources/api/src/modules.ts +0 -11
- package/template/sources/web/src/modules.ts +0 -22
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<html lang="
|
|
2
|
+
<html lang="__APP_LANG__">
|
|
3
3
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="UTF-8" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<meta name="application-name" content="__APP_NAME__" />
|
|
8
|
+
<meta name="description" content="__APP_DESCRIPTION__" />
|
|
7
9
|
<title>__APP_NAME__</title>
|
|
8
10
|
</head>
|
|
9
11
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { makeContext as makeBasicContext, useContext as useBasicContext } from '@owlmeans/web-panel'
|
|
2
|
+
import type { Config, Context } from './types.js'
|
|
3
|
+
|
|
4
|
+
export const useContext = (): Context => useBasicContext<Config, Context>()
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The framework's client store lives ON the context, so a screen, a guard and a service all
|
|
8
|
+
* reach the same records — which is what separates it from a store held beside the app in a
|
|
9
|
+
* module of its own. `appendStateResource<C, T>(context, ALIAS)` from '@owlmeans/state'
|
|
10
|
+
* (already a dependency) registers one; screens then address it by that alias, never by path.
|
|
11
|
+
*/
|
|
12
|
+
export const makeContext = <C extends Config, T extends Context<C>>(cfg: C): T =>
|
|
13
|
+
makeBasicContext<C, T>(cfg)
|
|
@@ -15,9 +15,5 @@ export const makeContext = <C extends Config, T extends Context<C>>(cfg: C): T =
|
|
|
15
15
|
// the app in a module of its own.
|
|
16
16
|
appendStateResource<C, T>(context, SESSION_STATE)
|
|
17
17
|
|
|
18
|
-
// A child context has to inherit THIS factory, not the layer's. Without the line, a derived
|
|
19
|
-
// context is built without the resource registered above and every lookup on it throws.
|
|
20
|
-
context.makeContext = makeContext as typeof context.makeContext
|
|
21
|
-
|
|
22
18
|
return context
|
|
23
19
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BASE, entrypoint, entrypoints as baseEntrypoints, frontend, handler, HOME, route } from '@owlmeans/web-panel'
|
|
2
|
+
import { sharedEntrypoints } from '__APP_SLUG__-common'
|
|
3
|
+
import { MainLayout } from './layout/main.js'
|
|
4
|
+
import { HomeScreen } from './screens/home.js'
|
|
5
|
+
|
|
6
|
+
// Backend entrypoints arrive as declarations only — `elevate(entrypoints, alias)` (from
|
|
7
|
+
// '@owlmeans/web-panel') makes one callable here without giving it a component.
|
|
8
|
+
const entrypoints = [...baseEntrypoints, ...sharedEntrypoints]
|
|
9
|
+
|
|
10
|
+
// Frontend layout + screens. BASE renders the shared layout; HOME is its default child.
|
|
11
|
+
entrypoints.push(entrypoint(route(BASE, '/', frontend()), handler(MainLayout)))
|
|
12
|
+
entrypoints.push(entrypoint(route(HOME, '/', frontend({ default: true, parent: BASE })), handler(HomeScreen)))
|
|
13
|
+
|
|
14
|
+
export const appEntrypoints = entrypoints
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BASE, elevate, entrypoint, entrypoints as baseEntrypoints, frontend, handler, HOME, route } from '@owlmeans/web-panel'
|
|
2
|
+
import { session, sessionEntrypoints, web } from '__APP_SLUG__-common'
|
|
3
|
+
import { MainLayout } from './layout/main.js'
|
|
4
|
+
import { AboutScreen } from './screens/about.js'
|
|
5
|
+
import { HomeScreen } from './screens/home.js'
|
|
6
|
+
import { SessionScreen } from './screens/session.js'
|
|
7
|
+
|
|
8
|
+
const entrypoints = [...baseEntrypoints, ...sessionEntrypoints]
|
|
9
|
+
|
|
10
|
+
// Backend entrypoints — elevated without a component so the client can call them.
|
|
11
|
+
elevate(entrypoints, session.base)
|
|
12
|
+
elevate(entrypoints, session.list)
|
|
13
|
+
elevate(entrypoints, session.add)
|
|
14
|
+
elevate(entrypoints, session.remove)
|
|
15
|
+
|
|
16
|
+
// Frontend layout + screens. BASE renders the shared layout; HOME is its default child.
|
|
17
|
+
entrypoints.push(entrypoint(route(BASE, '/', frontend()), handler(MainLayout)))
|
|
18
|
+
entrypoints.push(entrypoint(route(HOME, '/', frontend({ default: true, parent: BASE })), handler(HomeScreen)))
|
|
19
|
+
entrypoints.push(entrypoint(route(web.session, '/session', frontend({ parent: BASE })), handler(SessionScreen)))
|
|
20
|
+
entrypoints.push(entrypoint(route(web.about, '/about', frontend({ parent: BASE })), handler(AboutScreen)))
|
|
21
|
+
|
|
22
|
+
export const appEntrypoints = entrypoints
|
|
@@ -2,12 +2,12 @@ import './index.css'
|
|
|
2
2
|
import { APP_API, APP_WEB } from '__APP_SLUG__-common'
|
|
3
3
|
import config from './config.js'
|
|
4
4
|
import { makeContext } from './context.js'
|
|
5
|
-
import {
|
|
5
|
+
import { appEntrypoints } from './entrypoints.js'
|
|
6
6
|
import { render } from './render.js'
|
|
7
7
|
import type { Config, Context } from './types.js'
|
|
8
8
|
|
|
9
9
|
const context = makeContext<Config, Context>(config)
|
|
10
|
-
context.registerEntrypoints(
|
|
10
|
+
context.registerEntrypoints(appEntrypoints)
|
|
11
11
|
|
|
12
12
|
context.serviceRoute(APP_WEB, true)
|
|
13
13
|
context.serviceRoute(APP_API, true)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { HOME } from '@owlmeans/web-panel'
|
|
2
|
+
import type { PanelNavConfig, PanelNavLink } from '@owlmeans/web-panel'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The application's navigation, as data.
|
|
6
|
+
*
|
|
7
|
+
* Sections are the top menu; their items are the side menu of whichever section is active.
|
|
8
|
+
* A section holding ONE item renders no side menu at all — which is why the single-screen
|
|
9
|
+
* shell below shows none. Labels here are literal; drop them to fall back on the panel i18n
|
|
10
|
+
* keys (`nav.<section>` / `modules.<alias>`) instead.
|
|
11
|
+
*/
|
|
12
|
+
export const navConfig: PanelNavConfig = {
|
|
13
|
+
sections: [
|
|
14
|
+
{ name: 'home', label: 'Home', items: [{ alias: HOME, label: 'Overview' }] },
|
|
15
|
+
],
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const footerLinks: PanelNavLink[] = [
|
|
19
|
+
{ alias: HOME, label: '__APP_NAME__' },
|
|
20
|
+
{ href: 'https://owlmeans.com', label: 'OwlMeans', open: true },
|
|
21
|
+
]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FC } from 'react'
|
|
2
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
|
3
|
+
|
|
4
|
+
export const HomeScreen: FC = () => (
|
|
5
|
+
<Card>
|
|
6
|
+
<CardHeader>
|
|
7
|
+
<CardTitle>__APP_NAME__</CardTitle>
|
|
8
|
+
<CardDescription>__APP_DESCRIPTION__</CardDescription>
|
|
9
|
+
</CardHeader>
|
|
10
|
+
<CardContent>
|
|
11
|
+
<p className="text-sm text-muted-foreground">
|
|
12
|
+
Screens live in <code>src/screens</code>, the menu that reaches them in
|
|
13
|
+
{' '}<code>src/nav.ts</code>, and the routes they hang off in <code>src/entrypoints.ts</code>.
|
|
14
|
+
</p>
|
|
15
|
+
</CardContent>
|
|
16
|
+
</Card>
|
|
17
|
+
)
|
|
@@ -33,15 +33,15 @@ export const SessionScreen: FC = () => {
|
|
|
33
33
|
*/
|
|
34
34
|
const items = useStoreList<SessionItem>({ query: {}, resource: SESSION_STATE })
|
|
35
35
|
|
|
36
|
-
// The server is the source of truth; the store is what the screen reads. Fetch once,
|
|
37
|
-
// what came back
|
|
36
|
+
// The server is the source of truth; the store is what the screen reads. Fetch once, install
|
|
37
|
+
// what came back, and let the subscription render it. `replace` rather than a save per item:
|
|
38
|
+
// the endpoint answers with the session's whole set, so an item removed on another tab has to
|
|
39
|
+
// leave the store too, and one write wakes the subscribers once instead of once per record.
|
|
38
40
|
const load = async () => {
|
|
39
|
-
const
|
|
41
|
+
const data = await ctx
|
|
40
42
|
.entrypoint<ClientEntrypoint<SessionItem[]>>(session.list)
|
|
41
43
|
.call({ params: { sid } })
|
|
42
|
-
|
|
43
|
-
await store.save(item)
|
|
44
|
-
}
|
|
44
|
+
await store.replace(data ?? [])
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
useEffect(() => { void load() }, [])
|
|
@@ -50,7 +50,7 @@ export const SessionScreen: FC = () => {
|
|
|
50
50
|
if (text.trim() === '') return
|
|
51
51
|
setBusy(true)
|
|
52
52
|
try {
|
|
53
|
-
const
|
|
53
|
+
const item = await ctx
|
|
54
54
|
.entrypoint<ClientEntrypoint<SessionItem>>(session.add)
|
|
55
55
|
.call({ params: { sid }, body: { text } })
|
|
56
56
|
setText('')
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { elevate, modules } from '@owlmeans/server-app'
|
|
2
|
-
import { session, sessionModules } from '__APP_SLUG__-common'
|
|
3
|
-
import * as handlers from './app/session/index.js'
|
|
4
|
-
|
|
5
|
-
// Attach handler implementations to the shared entrypoint declarations.
|
|
6
|
-
elevate(sessionModules, session.base)
|
|
7
|
-
elevate(sessionModules, session.list, handlers.list)
|
|
8
|
-
elevate(sessionModules, session.add, handlers.add)
|
|
9
|
-
elevate(sessionModules, session.remove, handlers.remove)
|
|
10
|
-
|
|
11
|
-
export const appModules = [...modules, ...sessionModules]
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { BASE, elevate, entrypoint, frontend, handler, HOME, modules as baseModules, route } from '@owlmeans/web-panel'
|
|
2
|
-
import { session, sessionModules, web } from '__APP_SLUG__-common'
|
|
3
|
-
import { MainLayout } from './layout/main.js'
|
|
4
|
-
import { AboutScreen } from './screens/about.js'
|
|
5
|
-
import { HomeScreen } from './screens/home.js'
|
|
6
|
-
import { SessionScreen } from './screens/session.js'
|
|
7
|
-
|
|
8
|
-
const modules = [...baseModules, ...sessionModules]
|
|
9
|
-
|
|
10
|
-
// Backend entrypoints — elevated without a component so the client can call them.
|
|
11
|
-
elevate(modules, session.base)
|
|
12
|
-
elevate(modules, session.list)
|
|
13
|
-
elevate(modules, session.add)
|
|
14
|
-
elevate(modules, session.remove)
|
|
15
|
-
|
|
16
|
-
// Frontend layout + screens. BASE renders the shared layout; HOME is its default child.
|
|
17
|
-
modules.push(entrypoint(route(BASE, '/', frontend()), handler(MainLayout)))
|
|
18
|
-
modules.push(entrypoint(route(HOME, '/', frontend({ default: true, parent: BASE })), handler(HomeScreen)))
|
|
19
|
-
modules.push(entrypoint(route(web.session, '/session', frontend({ parent: BASE })), handler(SessionScreen)))
|
|
20
|
-
modules.push(entrypoint(route(web.about, '/about', frontend({ parent: BASE })), handler(AboutScreen)))
|
|
21
|
-
|
|
22
|
-
export const appModules = modules
|