@owlmeans/create-app 0.1.18-rc.6 → 0.1.18-rc.60
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 +49 -5
- package/build/args/types.d.ts +9 -0
- package/build/args/types.d.ts.map +1 -0
- package/build/args/types.js +2 -0
- package/build/args/types.js.map +1 -0
- package/build/args.d.ts +3 -20
- package/build/args.d.ts.map +1 -1
- package/build/args.js +121 -88
- package/build/args.js.map +1 -1
- package/build/bin.js +3 -3
- package/build/bin.js.map +1 -1
- package/build/consts.d.ts +6 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +6 -0
- package/build/consts.js.map +1 -0
- package/build/consts.local.d.ts +12 -0
- package/build/consts.local.d.ts.map +1 -0
- package/build/consts.local.js +49 -0
- package/build/consts.local.js.map +1 -0
- package/build/index.d.ts +11 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5 -2
- package/build/index.js.map +1 -1
- package/build/naming/types.d.ts +14 -0
- package/build/naming/types.d.ts.map +1 -0
- package/build/naming/types.js +2 -0
- package/build/naming/types.js.map +1 -0
- package/build/naming.d.ts +4 -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 +1 -1
- package/build/run.d.ts.map +1 -1
- package/build/run.js +23 -17
- package/build/run.js.map +1 -1
- package/build/scaffold.d.ts +8 -0
- package/build/scaffold.d.ts.map +1 -0
- package/build/scaffold.js +19 -0
- package/build/scaffold.js.map +1 -0
- package/build/template/types.d.ts +16 -0
- package/build/template/types.d.ts.map +1 -0
- package/build/template/types.js +2 -0
- package/build/template/types.js.map +1 -0
- package/build/template.d.ts +3 -16
- package/build/template.d.ts.map +1 -1
- package/build/template.js +69 -52
- package/build/template.js.map +1 -1
- package/build/types.d.ts +61 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/package.json +5 -4
- package/template/AGENTS.md +61 -2
- package/template/README.bare.md +70 -0
- package/template/README.md +9 -60
- package/template/_agents/scripts/link-skills.sh +327 -15
- package/template/_agents/skills/agent-memory/SKILL.md +12 -11
- package/template/_agents/skills/getting-started/SKILL.md +38 -79
- package/template/_agents/skills/logging/SKILL.md +38 -0
- package/template/_agents/skills/memory-promotion/SKILL.md +10 -4
- package/template/_agents/skills/memory-recompact/SKILL.md +15 -14
- package/template/_agents/skills/owlmeans-code-structure/SKILL.md +182 -0
- package/template/_agents/skills/reuse-code/SKILL.md +56 -10
- package/template/_agents/skills/self-education/SKILL.md +25 -5
- package/template/_agents/skills/skill-authoring/SKILL.md +78 -12
- package/template/_bare.json +24 -0
- package/template/_gitignore +8 -0
- package/template/bunfig.toml +2 -0
- package/template/package.json +3 -2
- package/template/sources/api/package.json +5 -4
- package/template/sources/api/src/app/session/add.ts +6 -17
- package/template/sources/api/src/app/session/list.ts +6 -12
- package/template/sources/api/src/app/session/remove.ts +6 -15
- package/template/sources/api/src/config.ts +7 -0
- package/template/sources/api/src/context.bare.ts +11 -0
- package/template/sources/api/src/entrypoints.bare.ts +4 -0
- package/template/sources/api/src/entrypoints.ts +13 -0
- package/template/sources/api/src/index.ts +8 -2
- package/template/sources/api/src/models/session/types.ts +14 -0
- package/template/sources/api/src/models/session.ts +43 -0
- package/template/sources/api/src/types.bare.ts +5 -0
- package/template/sources/common/package.json +8 -8
- package/template/sources/common/src/config.ts +2 -1
- package/template/sources/common/src/consts.bare.ts +8 -0
- package/template/sources/common/src/consts.ts +0 -13
- package/template/sources/common/src/entrypoints.bare.ts +14 -0
- package/template/sources/common/src/entrypoints.ts +60 -0
- package/template/sources/common/src/index.bare.ts +3 -0
- package/template/sources/common/src/index.ts +1 -1
- package/template/sources/common/src/schemas.ts +7 -7
- package/template/sources/web/index.html +3 -1
- package/template/sources/web/package.json +33 -30
- package/template/sources/web/src/components/ui/dropdown-menu.tsx +257 -0
- package/template/sources/web/src/components/ui/navigation-menu.tsx +169 -0
- package/template/sources/web/src/config.ts +8 -0
- package/template/sources/web/src/consts.ts +14 -0
- package/template/sources/web/src/context.bare.ts +13 -0
- package/template/sources/web/src/context.ts +12 -2
- package/template/sources/web/src/entrypoints.bare.ts +13 -0
- package/template/sources/web/src/entrypoints.ts +16 -0
- package/template/sources/web/src/index.css +7 -0
- package/template/sources/web/src/index.tsx +2 -2
- package/template/sources/web/src/layout/main.tsx +17 -19
- package/template/sources/web/src/nav.bare.ts +23 -0
- package/template/sources/web/src/nav.ts +23 -0
- package/template/sources/web/src/screens/about.tsx +19 -0
- package/template/sources/web/src/screens/home.bare.tsx +17 -0
- package/template/sources/web/src/screens/session.tsx +30 -17
- package/template/sources/web/src/vite-env.d.ts +8 -0
- package/template/sources/web/vite.config.ts +3 -2
- package/template/CLAUDE.md +0 -13
- package/template/sources/api/src/modules.ts +0 -11
- package/template/sources/common/src/modules.ts +0 -26
- package/template/sources/web/src/components/nav/main.tsx +0 -15
- package/template/sources/web/src/modules.ts +0 -20
package/build/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,YAAY,CAAA;AAQ5D,eAAO,MAAM,GAAG,SAAgB,UAAU,KAAG,OAAO,CAAC,MAAM,CAyF1D,CAAA"}
|
package/build/run.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import {
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
3
|
import { run as installSkills } from '@owlmeans/agent-skills';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
.toLowerCase()
|
|
7
|
-
.replace(/[^a-z0-9-]+/g, '-')
|
|
8
|
-
.replace(/^-+|-+$/g, '')
|
|
9
|
-
|| 'owlmeans-app';
|
|
10
|
-
const titleize = (slug) => slug.split('-').filter(Boolean).map(w => w[0].toUpperCase() + w.slice(1)).join(' ');
|
|
4
|
+
import { namingHelper } from './naming.js';
|
|
5
|
+
import { templateHelper } from './template.js';
|
|
11
6
|
const installArgs = (pm) => pm === 'yarn' ? [] : ['install'];
|
|
12
7
|
const log = (msg) => { process.stdout.write(msg + '\n'); };
|
|
13
8
|
export const run = async (args) => {
|
|
@@ -16,15 +11,23 @@ export const run = async (args) => {
|
|
|
16
11
|
return 2;
|
|
17
12
|
}
|
|
18
13
|
const dest = resolve(args.dir);
|
|
19
|
-
const slug = slugify(args.dir);
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
const slug = args.slug ?? namingHelper.slugify(args.dir);
|
|
15
|
+
if (!namingHelper.isValidSlug(slug)) {
|
|
16
|
+
process.stderr.write(`error: cannot derive a package slug from "${args.dir}" (got "${slug}")`
|
|
17
|
+
+ ' — pass one with --slug\n');
|
|
18
|
+
return 2;
|
|
19
|
+
}
|
|
20
|
+
const name = args.name ?? namingHelper.titleize(slug);
|
|
21
|
+
const description = args.description ?? namingHelper.defaultDescription(name);
|
|
22
|
+
if (!templateHelper.isEmptyDir(dest) && !args.yes) {
|
|
22
23
|
process.stderr.write(`error: ${dest} is not empty. Re-run with --yes to scaffold into it anyway.\n`);
|
|
23
24
|
return 1;
|
|
24
25
|
}
|
|
25
26
|
log(`\nScaffolding OwlMeans app "${name}" into ${dest}\n`);
|
|
26
|
-
copyTemplate(templateDir(), dest, { slug, name });
|
|
27
|
-
log(
|
|
27
|
+
templateHelper.copyTemplate(templateHelper.templateDir(), dest, { slug, name, lang: args.lang, description }, { bare: args.bare });
|
|
28
|
+
log(args.bare
|
|
29
|
+
? ' ✓ template copied (common + api + web, bare shell)'
|
|
30
|
+
: ' ✓ template copied (common + api + web)');
|
|
28
31
|
if (args.git) {
|
|
29
32
|
const git = spawnSync('git', ['init', '-q'], { cwd: dest, stdio: 'ignore' });
|
|
30
33
|
if (git.status === 0)
|
|
@@ -47,7 +50,7 @@ export const run = async (args) => {
|
|
|
47
50
|
log(args.install
|
|
48
51
|
? '\nDeploying agent skills via @owlmeans/agent-skills…'
|
|
49
52
|
: '\nDeploying harness guidance via @owlmeans/agent-skills (general skills only — re-run'
|
|
50
|
-
+ '\n`npx @owlmeans/agent-skills` after installing to add the package-specific ones)…');
|
|
53
|
+
+ '\n`npx @owlmeans/agent-skills@^0.1.18-rc.51` after installing to add the package-specific ones)…');
|
|
51
54
|
try {
|
|
52
55
|
const result = await installSkills({
|
|
53
56
|
dir: dest,
|
|
@@ -59,7 +62,7 @@ export const run = async (args) => {
|
|
|
59
62
|
help: false,
|
|
60
63
|
});
|
|
61
64
|
if (result.code !== 0) {
|
|
62
|
-
process.stderr.write(` agent-skills exited with code ${result.code} — you can re-run \`npx @owlmeans/agent-skills\` later.\n`);
|
|
65
|
+
process.stderr.write(` agent-skills exited with code ${result.code} — you can re-run \`npx @owlmeans/agent-skills@^0.1.18-rc.51\` later.\n`);
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
68
|
catch (err) {
|
|
@@ -74,8 +77,11 @@ export const run = async (args) => {
|
|
|
74
77
|
log(` ${installCmd}`);
|
|
75
78
|
log(` ${runCmd}\n`);
|
|
76
79
|
log('The web app starts on http://localhost:3001 and the API on http://localhost:3000.');
|
|
77
|
-
log(
|
|
78
|
-
|
|
80
|
+
log(args.bare
|
|
81
|
+
? 'Add your entrypoints in sources/common/src/entrypoints.ts, handlers in sources/api\n'
|
|
82
|
+
+ 'and screens in sources/web/src/screens — the Home screen shows where they go.\n'
|
|
83
|
+
: 'Open the "Session" page to exercise the in-memory session resource.\n');
|
|
84
|
+
log('Agent guidance was scaffolded: AGENTS.md, the skills in');
|
|
79
85
|
log('.agents/skills/ and the shared memory store at .agents/memory/MEMORY.md.');
|
|
80
86
|
log('Open the project in any coding agent — on the first session it will ask what the');
|
|
81
87
|
log('project is for and fill in its purpose for you.\n');
|
package/build/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ScaffoldOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Filesystem-only scaffolding for tools that drive create-app themselves: no git, no
|
|
4
|
+
* dependency install, no agent-skills deploy, no output. Everything the CLI adds around
|
|
5
|
+
* the copy is the CLI's business — a caller that wants it calls `run` instead.
|
|
6
|
+
*/
|
|
7
|
+
export declare const scaffold: (opts: ScaffoldOptions) => void;
|
|
8
|
+
//# sourceMappingURL=scaffold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;GAIG;AACH,eAAO,MAAM,QAAQ,SAAU,eAAe,KAAG,IAShD,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { namingHelper } from './naming.js';
|
|
3
|
+
import { DEFAULT_LANG } from './consts.js';
|
|
4
|
+
import { templateHelper } from './template.js';
|
|
5
|
+
/**
|
|
6
|
+
* Filesystem-only scaffolding for tools that drive create-app themselves: no git, no
|
|
7
|
+
* dependency install, no agent-skills deploy, no output. Everything the CLI adds around
|
|
8
|
+
* the copy is the CLI's business — a caller that wants it calls `run` instead.
|
|
9
|
+
*/
|
|
10
|
+
export const scaffold = (opts) => {
|
|
11
|
+
const name = opts.name ?? namingHelper.titleize(opts.slug);
|
|
12
|
+
templateHelper.copyTemplate(templateHelper.templateDir(), resolve(opts.dir), {
|
|
13
|
+
slug: opts.slug,
|
|
14
|
+
name,
|
|
15
|
+
lang: opts.lang ?? DEFAULT_LANG,
|
|
16
|
+
description: opts.description ?? namingHelper.defaultDescription(name),
|
|
17
|
+
}, { bare: opts.bare === true });
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAG9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAqB,EAAQ,EAAE;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE1D,cAAc,CAAC,YAAY,CAAC,cAAc,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAC3E,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI;QACJ,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,YAAY;QAC/B,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,YAAY,CAAC,kBAAkB,CAAC,IAAI,CAAC;KACvE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,CAAA;AAClC,CAAC,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CopyTemplateOptions, TemplateReplacements } from '../types.js';
|
|
2
|
+
/** The bundled `template/` tree and its copy into a new project. */
|
|
3
|
+
export interface TemplateHelper {
|
|
4
|
+
/** Absolute path to the bundled `template/` directory (sibling of `build/`). */
|
|
5
|
+
templateDir: () => string;
|
|
6
|
+
/**
|
|
7
|
+
* Recursively copy `src` → `dest`, substituting the `__APP_*__` placeholders in text files
|
|
8
|
+
* and renaming shipped dotfiles (`_gitignore` → `.gitignore`). With `bare` the template's
|
|
9
|
+
* `_bare.json` decides what is dropped and which `.bare.` variant supplies the content, so
|
|
10
|
+
* the demo inventory lives in the template rather than in this code.
|
|
11
|
+
*/
|
|
12
|
+
copyTemplate: (src: string, dest: string, r: TemplateReplacements, opts?: CopyTemplateOptions) => void;
|
|
13
|
+
/** Whether a directory is missing or has no entries. */
|
|
14
|
+
isEmptyDir: (dir: string) => boolean;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/template/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAE5E,oEAAoE;AACpE,MAAM,WAAW,cAAc;IAC7B,gFAAgF;IAChF,WAAW,EAAE,MAAM,MAAM,CAAA;IACzB;;;;;OAKG;IACH,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,oBAAoB,EAAE,IAAI,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAA;IACtG,wDAAwD;IACxD,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/template/types.ts"],"names":[],"mappings":""}
|
package/build/template.d.ts
CHANGED
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
slug: string;
|
|
5
|
-
/** human-readable name, e.g. `My App` */
|
|
6
|
-
name: string;
|
|
7
|
-
}
|
|
8
|
-
/** Absolute path to the bundled `template/` directory (sibling of `build/`). */
|
|
9
|
-
export declare const templateDir: () => string;
|
|
10
|
-
/**
|
|
11
|
-
* Recursively copy `src` → `dest`, substituting `__APP_SLUG__` / `__APP_NAME__`
|
|
12
|
-
* in text files and renaming shipped dotfiles (`_gitignore` → `.gitignore`).
|
|
13
|
-
*/
|
|
14
|
-
export declare const copyTemplate: (src: string, dest: string, r: TemplateReplacements) => void;
|
|
15
|
-
export declare const isEmptyDir: (dir: string) => boolean;
|
|
16
|
-
export { renameSync };
|
|
1
|
+
import type { TemplateHelper } from './template/types.js';
|
|
2
|
+
export declare const createTemplateHelper: () => TemplateHelper;
|
|
3
|
+
export declare const templateHelper: TemplateHelper;
|
|
17
4
|
//# sourceMappingURL=template.d.ts.map
|
package/build/template.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEzD,eAAO,MAAM,oBAAoB,QAAO,cA4FvC,CAAA;AAED,eAAO,MAAM,cAAc,gBAAyB,CAAA"}
|
package/build/template.js
CHANGED
|
@@ -1,57 +1,74 @@
|
|
|
1
|
-
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync,
|
|
1
|
+
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import { dirname, join, resolve } from 'node:path';
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
*
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
for (const entry of readdirSync(src)) {
|
|
36
|
-
const from = join(src, entry);
|
|
37
|
-
const targetName = DOTFILE_RENAMES[entry] ?? entry;
|
|
38
|
-
const to = join(dest, targetName);
|
|
39
|
-
if (statSync(from).isDirectory()) {
|
|
40
|
-
copyTemplate(from, to, r);
|
|
41
|
-
continue;
|
|
3
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
4
|
+
import { BARE_MANIFEST, BINARY_EXT, DOTFILE_RENAMES, GLOBSTAR } from './consts.local.js';
|
|
5
|
+
export const createTemplateHelper = () => {
|
|
6
|
+
const templateDir = () => resolve(dirname(fileURLToPath(import.meta.url)), '..', 'template');
|
|
7
|
+
const applyReplacements = (content, r) => content
|
|
8
|
+
.replaceAll('__APP_SLUG__', r.slug)
|
|
9
|
+
.replaceAll('__APP_NAME__', r.name)
|
|
10
|
+
.replaceAll('__APP_LANG__', r.lang)
|
|
11
|
+
.replaceAll('__APP_DESCRIPTION__', r.description);
|
|
12
|
+
const isBinary = (file) => {
|
|
13
|
+
const dot = file.lastIndexOf('.');
|
|
14
|
+
return dot >= 0 && BINARY_EXT.has(file.slice(dot).toLowerCase());
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Bare variants sit beside the files they replace so the normal template still compiles as
|
|
18
|
+
* one project — which is also why they are filtered out of the copy in BOTH modes.
|
|
19
|
+
*/
|
|
20
|
+
const isBareVariant = (entry) => entry.includes('.bare.');
|
|
21
|
+
const globToRegExp = (pattern) => new RegExp('^' + pattern
|
|
22
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
23
|
+
.replaceAll('**/', GLOBSTAR)
|
|
24
|
+
.replace(/\*/g, '[^/]*')
|
|
25
|
+
.replaceAll(GLOBSTAR, '(?:.*/)?')
|
|
26
|
+
+ '$');
|
|
27
|
+
const isRemoved = (rel, patterns) => patterns.some(pattern => rel === pattern
|
|
28
|
+
// A directory pattern takes its whole subtree — the walk simply never descends into it.
|
|
29
|
+
|| rel.startsWith(pattern.endsWith('/') ? pattern : pattern + '/')
|
|
30
|
+
|| (pattern.includes('*') && globToRegExp(pattern).test(rel)));
|
|
31
|
+
const readBareManifest = (root) => {
|
|
32
|
+
const file = join(root, BARE_MANIFEST);
|
|
33
|
+
if (!existsSync(file)) {
|
|
34
|
+
throw new Error(`bare scaffolding requires ${BARE_MANIFEST} in the template (${root})`);
|
|
42
35
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
const parsed = JSON.parse(readFileSync(file, 'utf8'));
|
|
37
|
+
return { remove: parsed.remove ?? [], overrides: parsed.overrides ?? {} };
|
|
38
|
+
};
|
|
39
|
+
const toPosix = (path) => path.split(sep).join('/');
|
|
40
|
+
const copyTree = (src, dest, r, root, bare) => {
|
|
41
|
+
mkdirSync(dest, { recursive: true });
|
|
42
|
+
for (const entry of readdirSync(src)) {
|
|
43
|
+
const from = join(src, entry);
|
|
44
|
+
const rel = toPosix(relative(root, from));
|
|
45
|
+
if (rel === BARE_MANIFEST || isBareVariant(entry))
|
|
46
|
+
continue;
|
|
47
|
+
if (bare != null && isRemoved(rel, bare.remove))
|
|
48
|
+
continue;
|
|
49
|
+
const to = join(dest, DOTFILE_RENAMES[entry] ?? entry);
|
|
50
|
+
if (statSync(from).isDirectory()) {
|
|
51
|
+
copyTree(from, to, r, root, bare);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const override = bare?.overrides[rel];
|
|
55
|
+
const source = override != null ? join(root, override) : from;
|
|
56
|
+
if (isBinary(source)) {
|
|
57
|
+
cpSync(source, to);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
writeFileSync(to, applyReplacements(readFileSync(source, 'utf8'), r));
|
|
46
61
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
};
|
|
63
|
+
const copyTemplate = (src, dest, r, opts = {}) => {
|
|
64
|
+
copyTree(src, dest, r, src, opts.bare === true ? readBareManifest(src) : null);
|
|
65
|
+
};
|
|
66
|
+
const isEmptyDir = (dir) => {
|
|
67
|
+
if (!existsSync(dir))
|
|
68
|
+
return true;
|
|
69
|
+
return readdirSync(dir).length === 0;
|
|
70
|
+
};
|
|
71
|
+
return { templateDir, copyTemplate, isEmptyDir };
|
|
55
72
|
};
|
|
56
|
-
export
|
|
73
|
+
export const templateHelper = createTemplateHelper();
|
|
57
74
|
//# sourceMappingURL=template.js.map
|
package/build/template.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"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"}
|
package/build/types.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export type PackageManager = 'bun' | 'npm' | 'yarn';
|
|
2
|
+
export interface CreateArgs {
|
|
3
|
+
/** Target directory (positional). `null` means it must be prompted/derived. */
|
|
4
|
+
dir: string | null;
|
|
5
|
+
/** Human-readable app name. Defaults to the directory slug. */
|
|
6
|
+
name: string | null;
|
|
7
|
+
/** Explicit package slug. `null` derives it from the target directory. */
|
|
8
|
+
slug: string | null;
|
|
9
|
+
/** BCP-47-ish language of the generated UI text and `<html lang>`. */
|
|
10
|
+
lang: string;
|
|
11
|
+
/** One-line project description for the README, AGENTS.md and the index.html meta tags. */
|
|
12
|
+
description: string | null;
|
|
13
|
+
/** Scaffold the shell without the example/demo code. */
|
|
14
|
+
bare: boolean;
|
|
15
|
+
/** Package manager used to install deps and (for `bun`) run the project. */
|
|
16
|
+
pm: PackageManager;
|
|
17
|
+
/** Install dependencies after copying the template. */
|
|
18
|
+
install: boolean;
|
|
19
|
+
/** Deploy agent skills via @owlmeans/agent-skills after install. */
|
|
20
|
+
skills: boolean;
|
|
21
|
+
/** Run `git init` in the new project. */
|
|
22
|
+
git: boolean;
|
|
23
|
+
/** Skip confirmations / proceed into a non-empty directory. */
|
|
24
|
+
yes: boolean;
|
|
25
|
+
help: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface ScaffoldOptions {
|
|
28
|
+
/** Destination directory. Created when missing; an existing one is written into as-is. */
|
|
29
|
+
dir: string;
|
|
30
|
+
/** package/workspace slug, e.g. `my-app`. */
|
|
31
|
+
slug: string;
|
|
32
|
+
/** Human-readable name. Defaults to the titleized slug. */
|
|
33
|
+
name?: string;
|
|
34
|
+
/** BCP-47-ish UI language and `<html lang>`. Defaults to `en`. */
|
|
35
|
+
lang?: string;
|
|
36
|
+
/** One-line description for the README, AGENTS.md and the index.html meta tags. */
|
|
37
|
+
description?: string;
|
|
38
|
+
/** Scaffold the shell without the example/demo code. */
|
|
39
|
+
bare?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface BareManifest {
|
|
42
|
+
/** Template-relative paths — a file, a directory subtree, or a `*` / `**` glob — the bare shell omits. */
|
|
43
|
+
remove: string[];
|
|
44
|
+
/** Target template path → the `.bare.`-infixed source whose CONTENT is written there instead. */
|
|
45
|
+
overrides: Record<string, string>;
|
|
46
|
+
}
|
|
47
|
+
export interface TemplateReplacements {
|
|
48
|
+
/** package/workspace slug, e.g. `my-app` */
|
|
49
|
+
slug: string;
|
|
50
|
+
/** human-readable name, e.g. `My App` */
|
|
51
|
+
name: string;
|
|
52
|
+
/** BCP-47-ish UI language, e.g. `en` — also the generated `<html lang>` */
|
|
53
|
+
lang: string;
|
|
54
|
+
/** one-line project description for the README, AGENTS.md and the index.html meta tags */
|
|
55
|
+
description: string;
|
|
56
|
+
}
|
|
57
|
+
export interface CopyTemplateOptions {
|
|
58
|
+
/** Scaffold the demo-free shell: apply `_bare.json`'s removals and overrides. */
|
|
59
|
+
bare?: boolean;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;AAEnD,MAAM,WAAW,UAAU;IACzB,+EAA+E;IAC/E,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAA;IACZ,2FAA2F;IAC3F,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,wDAAwD;IACxD,IAAI,EAAE,OAAO,CAAA;IACb,4EAA4E;IAC5E,EAAE,EAAE,cAAc,CAAA;IAClB,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAA;IAChB,oEAAoE;IACpE,MAAM,EAAE,OAAO,CAAA;IACf,yCAAyC;IACzC,GAAG,EAAE,OAAO,CAAA;IACZ,+DAA+D;IAC/D,GAAG,EAAE,OAAO,CAAA;IACZ,IAAI,EAAE,OAAO,CAAA;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,0FAA0F;IAC1F,GAAG,EAAE,MAAM,CAAA;IACX,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wDAAwD;IACxD,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,0GAA0G;IAC1G,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,iGAAiG;IACjG,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAA;IACZ,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAA;IACZ,0FAA0F;IAC1F,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,IAAI,CAAC,EAAE,OAAO,CAAA;CACf"}
|
package/build/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/create-app",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.60",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"description": "Scaffold a
|
|
5
|
+
"description": "Scaffold a fullstack OwlMeans Common app — common + api + web workspaces, shadcn UI navigation/layout, no auth, and a session-scoped in-memory resource, or --bare for the demo-free shell. Also usable programmatically via scaffold(). Deploys agent skills via @owlmeans/agent-skills by default.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc -b",
|
|
9
|
+
"test": "bun test ./tests",
|
|
9
10
|
"dev": "nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
|
|
10
11
|
"watch": "tsc -b -w --preserveWatchOutput --pretty"
|
|
11
12
|
},
|
|
@@ -29,11 +30,11 @@
|
|
|
29
30
|
"template"
|
|
30
31
|
],
|
|
31
32
|
"dependencies": {
|
|
32
|
-
"@owlmeans/agent-skills": "^0.1.18-rc.
|
|
33
|
+
"@owlmeans/agent-skills": "^0.1.18-rc.51"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@owlmeans/dep-config": "workspace:*",
|
|
36
|
-
"@types/node": "^26.
|
|
37
|
+
"@types/node": "^26.6.4",
|
|
37
38
|
"nodemon": "^3.1.14",
|
|
38
39
|
"typescript": "^7.0.2"
|
|
39
40
|
},
|
package/template/AGENTS.md
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Project purpose
|
|
4
4
|
|
|
5
|
+
__APP_DESCRIPTION__
|
|
6
|
+
|
|
5
7
|
<!-- OWLMEANS:PROJECT-PURPOSE -->
|
|
6
8
|
> **Agents — this project has not been described yet.** Before doing anything else on the first
|
|
7
9
|
> session, ask the user what this project is for: its purpose, domain, goals, and key constraints.
|
|
8
10
|
> Then replace this whole block with a short description of the project, and remove this notice.
|
|
11
|
+
<!-- /OWLMEANS:PROJECT-PURPOSE -->
|
|
9
12
|
|
|
10
13
|
## Git Workflow (mandatory)
|
|
11
14
|
|
|
@@ -27,6 +30,15 @@ skill.
|
|
|
27
30
|
- Report finished git work as a Markdown table (**Action**, **Target**, **Result**), and never
|
|
28
31
|
commit a conflicted working copy — stop, list the conflicted paths, hand control back.
|
|
29
32
|
|
|
33
|
+
## Code structure (mandatory)
|
|
34
|
+
|
|
35
|
+
The functions of one domain are ONE object built by a factory: its `interface` is declared first
|
|
36
|
+
(never `ReturnType<typeof …>`; interfaces over types wherever possible), the implementation and its
|
|
37
|
+
private parts live in the factory, and a shared context or collaborator is bound into the factory.
|
|
38
|
+
Types, consts and code live in separate files; an object with parts gets a same-named folder
|
|
39
|
+
(`x.ts` + `x/types.ts`). Load `/owlmeans-code-structure` before writing, moving or reviewing any
|
|
40
|
+
`.ts`/`.tsx`, and hold every diff to it.
|
|
41
|
+
|
|
30
42
|
## Reporting (mandatory)
|
|
31
43
|
|
|
32
44
|
Always report concisely and briefly, in table format, about WHAT was done rather than why —
|
|
@@ -76,20 +88,67 @@ package (in the installed packages and at https://github.com/owlmeans/common) or
|
|
|
76
88
|
already solves the problem **before** proposing a third-party library or a custom solution, and
|
|
77
89
|
simplify whatever you do write. This is required for every planning and development task.
|
|
78
90
|
|
|
91
|
+
## Runtime config advertisement
|
|
92
|
+
|
|
93
|
+
The config endpoint is default-deny. A backend config field reaches the browser only when the
|
|
94
|
+
package that owns its browser consumer imports `apiConfigPlugin({ allow, deny? })` from
|
|
95
|
+
`@owlmeans/api-config` at module scope. Name public nested fields precisely; use `every()` and a
|
|
96
|
+
nested `deny` selector when a public collection carries a credential. Databases, queues, SMTP,
|
|
97
|
+
tokens, secrets and internal addresses never belong in an `allow` selector.
|
|
98
|
+
|
|
99
|
+
## Logging (mandatory)
|
|
100
|
+
|
|
101
|
+
Before adding any log line, catch block or `console` call, follow the `logging` skill (mechanics: `log`).
|
|
102
|
+
|
|
103
|
+
- No `console.*`: `const log = logger('<scope>')` from `@owlmeans/log`, a deliberate level, the
|
|
104
|
+
`Error` itself to `log.error`; never secrets, tokens or personal content.
|
|
105
|
+
- The level is set per environment, never in code: the api reads `LOG_LEVEL` / `LOG_DEBUG`
|
|
106
|
+
(default `info`), the web build reads `VITE_LOG_LEVEL` / `VITE_LOG_DEBUG` (`debug` under `vite`,
|
|
107
|
+
`info` in a build). Local values go in the git-ignored `sources/api/.env` / `sources/web/.env`.
|
|
108
|
+
- Never set `cfg.debug = { all: true }` — it does not control logging and must not reach production.
|
|
109
|
+
|
|
79
110
|
## Skills
|
|
80
111
|
|
|
81
112
|
Reusable guidance lives in `.agents/skills/<name>/SKILL.md`, deployed by `@owlmeans/agent-skills`
|
|
82
113
|
from the installed `@owlmeans/*` packages. Agents load a skill by topic, or you run `/<name>`
|
|
83
114
|
explicitly. Copilot and Codex read `.agents/skills/` directly; Claude Code reads the generated
|
|
84
|
-
symlinks in `.claude/skills/` (see
|
|
115
|
+
symlinks in `.claude/skills/` (see "Claude Code" below).
|
|
85
116
|
|
|
86
|
-
- After adding or updating any `@owlmeans/*` dependency, run `npx @owlmeans/agent-skills` to refresh
|
|
117
|
+
- After adding or updating any `@owlmeans/*` dependency, run `npx @owlmeans/agent-skills@^0.1.18-rc.51` to refresh
|
|
87
118
|
the deployed skills.
|
|
119
|
+
- `/logging` — before adding any log line, catch block or `console` call (mechanics: `/log`).
|
|
88
120
|
- Deployed files carry an `AUTO-GENERATED` banner and are refreshed in place — never hand-edit them.
|
|
89
121
|
- To capture your own guidance, see the `skill-authoring` skill; to turn repeatedly-used memory into
|
|
90
122
|
a skill, `memory-promotion`. Keep it inside this repository, in `.agents/skills/` — never in a
|
|
91
123
|
per-agent or home directory.
|
|
92
124
|
|
|
125
|
+
<!-- OWLMEANS:LINKED-SKILLS -->
|
|
126
|
+
### Skills linked from installed packages
|
|
127
|
+
|
|
128
|
+
`sh .agents/scripts/link-skills.sh` also links in the skills that ship inside the installed
|
|
129
|
+
`@owlmeans/*` packages (`node_modules/@owlmeans/<pkg>/agent-meta/skills/<name>`), so they load
|
|
130
|
+
by name (`/<name>`) like a local skill. They land in `.agents/linked-skills/<name>` for Copilot
|
|
131
|
+
and Codex and in `.claude/skills/<name>` for Claude Code, with a `skill / origin repo /
|
|
132
|
+
description` table in `.agents/linked-skills/INDEX.md`. A local skill of the same name always
|
|
133
|
+
wins. The directory is generated and git-ignored — never edit or commit it.
|
|
134
|
+
|
|
135
|
+
The root `prepare` script runs it on every `bun install`, and a session-start hook runs it
|
|
136
|
+
again, so a fresh checkout carries the links for every agent — Copilot and Codex included,
|
|
137
|
+
not just Claude Code.
|
|
138
|
+
|
|
139
|
+
<!-- /OWLMEANS:LINKED-SKILLS -->
|
|
140
|
+
|
|
141
|
+
## Claude Code
|
|
142
|
+
|
|
143
|
+
Claude Code reads this file directly — there is no `CLAUDE.md`. Skills live only in
|
|
144
|
+
`.agents/skills/<name>/SKILL.md`, the single canonical location shared with Copilot and Codex.
|
|
145
|
+
`.claude/skills/` holds only generated per-skill symlinks (gitignored except `.gitkeep`); the
|
|
146
|
+
committed `SessionStart` hook runs `sh .agents/scripts/link-skills.sh` to (re)create them each session.
|
|
147
|
+
|
|
148
|
+
- Never author files under `.claude/skills/` — write skills in `.agents/skills/`.
|
|
149
|
+
- After creating, renaming, or deleting a skill, re-run
|
|
150
|
+
`sh .agents/scripts/link-skills.sh` so the session picks it up.
|
|
151
|
+
|
|
93
152
|
## Develop
|
|
94
153
|
|
|
95
154
|
```sh
|