@owlmeans/create-app 0.1.18-rc.2 → 0.1.18-rc.20

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.
Files changed (77) hide show
  1. package/README.md +38 -1
  2. package/build/args.d.ts +8 -0
  3. package/build/args.d.ts.map +1 -1
  4. package/build/args.js +60 -6
  5. package/build/args.js.map +1 -1
  6. package/build/index.d.ts +4 -1
  7. package/build/index.d.ts.map +1 -1
  8. package/build/index.js +2 -0
  9. package/build/index.js.map +1 -1
  10. package/build/naming.d.ts +11 -0
  11. package/build/naming.d.ts.map +1 -0
  12. package/build/naming.js +18 -0
  13. package/build/naming.js.map +1 -0
  14. package/build/run.d.ts.map +1 -1
  15. package/build/run.js +19 -13
  16. package/build/run.js.map +1 -1
  17. package/build/scaffold.d.ts +21 -0
  18. package/build/scaffold.d.ts.map +1 -0
  19. package/build/scaffold.js +18 -0
  20. package/build/scaffold.js.map +1 -0
  21. package/build/template.d.ts +19 -3
  22. package/build/template.d.ts.map +1 -1
  23. package/build/template.js +52 -12
  24. package/build/template.js.map +1 -1
  25. package/package.json +4 -3
  26. package/template/AGENTS.md +28 -1
  27. package/template/README.bare.md +57 -0
  28. package/template/README.md +5 -61
  29. package/template/_agents/scripts/link-skills.sh +310 -15
  30. package/template/_agents/skills/agent-memory/SKILL.md +12 -11
  31. package/template/_agents/skills/getting-started/SKILL.md +26 -86
  32. package/template/_agents/skills/memory-promotion/SKILL.md +10 -4
  33. package/template/_agents/skills/memory-recompact/SKILL.md +15 -14
  34. package/template/_agents/skills/reuse-code/SKILL.md +36 -8
  35. package/template/_agents/skills/self-education/SKILL.md +19 -5
  36. package/template/_agents/skills/skill-authoring/SKILL.md +53 -11
  37. package/template/_bare.json +23 -0
  38. package/template/_gitignore +3 -0
  39. package/template/bunfig.toml +2 -0
  40. package/template/package.json +3 -2
  41. package/template/sources/api/package.json +3 -3
  42. package/template/sources/api/src/app/session/add.ts +7 -6
  43. package/template/sources/api/src/app/session/list.ts +12 -9
  44. package/template/sources/api/src/app/session/remove.ts +7 -6
  45. package/template/sources/api/src/context.bare.ts +11 -0
  46. package/template/sources/api/src/entrypoints.bare.ts +4 -0
  47. package/template/sources/api/src/entrypoints.ts +13 -0
  48. package/template/sources/api/src/index.ts +2 -2
  49. package/template/sources/api/src/types.bare.ts +5 -0
  50. package/template/sources/common/package.json +6 -6
  51. package/template/sources/common/src/consts.bare.ts +8 -0
  52. package/template/sources/common/src/consts.ts +0 -13
  53. package/template/sources/common/src/entrypoints.bare.ts +14 -0
  54. package/template/sources/common/src/entrypoints.ts +60 -0
  55. package/template/sources/common/src/index.bare.ts +3 -0
  56. package/template/sources/common/src/index.ts +1 -1
  57. package/template/sources/common/src/schemas.ts +7 -7
  58. package/template/sources/web/index.html +3 -1
  59. package/template/sources/web/package.json +13 -11
  60. package/template/sources/web/src/components/ui/navigation-menu.tsx +169 -0
  61. package/template/sources/web/src/context.bare.ts +13 -0
  62. package/template/sources/web/src/context.ts +14 -2
  63. package/template/sources/web/src/entrypoints.bare.ts +13 -0
  64. package/template/sources/web/src/entrypoints.ts +16 -0
  65. package/template/sources/web/src/index.css +7 -0
  66. package/template/sources/web/src/index.tsx +2 -2
  67. package/template/sources/web/src/layout/main.tsx +16 -19
  68. package/template/sources/web/src/nav.bare.ts +21 -0
  69. package/template/sources/web/src/nav.ts +28 -0
  70. package/template/sources/web/src/screens/about.tsx +19 -0
  71. package/template/sources/web/src/screens/home.bare.tsx +17 -0
  72. package/template/sources/web/src/screens/session.tsx +28 -14
  73. package/template/sources/web/src/vite-env.d.ts +1 -0
  74. package/template/sources/api/src/modules.ts +0 -11
  75. package/template/sources/common/src/modules.ts +0 -26
  76. package/template/sources/web/src/components/nav/main.tsx +0 -15
  77. package/template/sources/web/src/modules.ts +0 -20
package/README.md CHANGED
@@ -9,7 +9,7 @@ bun create @owlmeans/app my-app
9
9
  # or
10
10
  yarn create @owlmeans/app my-app
11
11
  # or
12
- npx @owlmeans/create-app my-app
12
+ npx @owlmeans/create-app@^0.1.18-rc.14 my-app
13
13
  ```
14
14
 
15
15
  ## What it generates
@@ -49,6 +49,10 @@ is present even with `--no-install`.
49
49
  | Flag | Description |
50
50
  |------|-------------|
51
51
  | `--name <name>` | Human-readable app name (default: derived from the target dir) |
52
+ | `--slug <slug>` | Package slug, `^[a-z0-9](?:[a-z0-9-]{0,30}[a-z0-9])?$` (default: derived from the target dir) |
53
+ | `--lang <code>` | Language of the generated UI text and `<html lang>` (default: `en`) |
54
+ | `--description <text>` | One-line description used in `README.md`, `AGENTS.md`, the Home screen and the `index.html` meta tags |
55
+ | `--bare` | Scaffold the working shell with no example/demo code |
52
56
  | `--pm <bun\|npm\|yarn>` | Package manager (default: `bun`) |
53
57
  | `--no-install` | Skip dependency installation |
54
58
  | `--no-skills` | Skip the `@owlmeans/agent-skills` deploy |
@@ -56,6 +60,39 @@ is present even with `--no-install`.
56
60
  | `--yes`, `-y` | Proceed without prompts / into a non-empty directory |
57
61
  | `--help`, `-h` | Show help |
58
62
 
63
+ ## `--bare`
64
+
65
+ `--bare` keeps the three workspaces, the config/context/entrypoint wiring, the layout, the nav
66
+ skeleton and one Home screen, and drops every piece of example code — the `SessionItem` types and
67
+ schemas, the api's `app/session/**` handlers and its static resource, the About and Session screens.
68
+ `sources/common/src/entrypoints.ts` exports an immutable `appEntrypoints` tree with an empty `api`
69
+ branch and the web routes. The API and web bind those branches locally, so the first feature adds a
70
+ declaration to the tree, then a handler and a screen binding.
71
+
72
+ What bare removes and what it swaps in is declared in `template/_bare.json`, next to the
73
+ `.bare.`-infixed variants it points at — not in the scaffolder's code.
74
+
75
+ ## Programmatic use
76
+
77
+ `scaffold` performs the filesystem copy and nothing else: no `git init`, no install, no
78
+ agent-skills deploy, no logging. The destination directory may already exist.
79
+
80
+ ```ts
81
+ import { scaffold } from '@owlmeans/create-app'
82
+
83
+ scaffold({
84
+ dir: '/tmp/my-app',
85
+ slug: 'my-app',
86
+ name: 'My App', // default: the titleized slug
87
+ lang: 'en',
88
+ description: 'What the app is for.',
89
+ bare: true,
90
+ })
91
+ ```
92
+
93
+ `templateDir()`, `copyTemplate(src, dest, replacements, { bare })` and `isEmptyDir(dir)` are
94
+ exported for callers that want the pieces; `run(args)` is the full CLI flow.
95
+
59
96
  ## Running the generated app
60
97
 
61
98
  ```sh
package/build/args.d.ts CHANGED
@@ -4,6 +4,14 @@ export interface CreateArgs {
4
4
  dir: string | null;
5
5
  /** Human-readable app name. Defaults to the directory slug. */
6
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;
7
15
  /** Package manager used to install deps and (for `bun`) run the project. */
8
16
  pm: PackageManager;
9
17
  /** Install dependencies after copying the template. */
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.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,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;AA0BD,eAAO,MAAM,SAAS,SAAU,MAAM,EAAE,KAAG,UAAU,GAAG,IAsEvD,CAAA;AAED,eAAO,MAAM,SAAS,QAAO,IAE5B,CAAA"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAEA,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;AA+BD,eAAO,MAAM,SAAS,SAAU,MAAM,EAAE,KAAG,UAAU,GAAG,IAqHvD,CAAA;AAED,eAAO,MAAM,SAAS,QAAO,IAE5B,CAAA"}
package/build/args.js CHANGED
@@ -1,17 +1,23 @@
1
+ import { DEFAULT_LANG, isValidLang, isValidSlug, SLUG_PATTERN } from './naming.js';
1
2
  const HELP = `@owlmeans/create-app — scaffold a fullstack OwlMeans Common app
2
3
 
3
4
  Usage:
4
5
  npm create @owlmeans/app@latest <dir> [options]
5
6
  bun create @owlmeans/app <dir> [options]
6
7
  yarn create @owlmeans/app <dir> [options]
7
- npx @owlmeans/create-app <dir> [options]
8
+ npx @owlmeans/create-app@^0.1.18-rc.14 <dir> [options]
8
9
 
9
10
  Generates three workspaces (common + api + web) with shadcn UI navigation and
10
11
  layout, no authentication, and a session-scoped in-memory resource on the
11
- backend. Agent skills are deployed into the project by default.
12
+ backend. With --bare the demo is left out and only the working shell remains.
13
+ Agent skills are deployed into the project by default.
12
14
 
13
15
  Options:
14
16
  --name <name> human-readable app name (default: derived from <dir>)
17
+ --slug <slug> package slug (default: derived from <dir>)
18
+ --lang <code> language of the generated UI text (default: ${DEFAULT_LANG})
19
+ --description <t> one-line project description for the generated docs
20
+ --bare scaffold the shell only — no example/demo code
15
21
  --pm <bun|npm|yarn> package manager (default: bun)
16
22
  --no-install do not install dependencies
17
23
  --no-skills do not deploy agent skills via @owlmeans/agent-skills
@@ -25,6 +31,10 @@ export const parseArgs = (argv) => {
25
31
  const result = {
26
32
  dir: null,
27
33
  name: null,
34
+ slug: null,
35
+ lang: DEFAULT_LANG,
36
+ description: null,
37
+ bare: false,
28
38
  pm: 'bun',
29
39
  install: true,
30
40
  skills: true,
@@ -32,6 +42,16 @@ export const parseArgs = (argv) => {
32
42
  yes: false,
33
43
  help: false,
34
44
  };
45
+ // A value may legitimately start with `-` only for free-form text, so `--description`
46
+ // takes whatever follows it; the identifier-shaped flags stay strict.
47
+ const value = (i, flag, free = false) => {
48
+ const v = args[i + 1];
49
+ if (v == null || (!free && v.startsWith('-'))) {
50
+ process.stderr.write(`error: ${flag} requires a value\n`);
51
+ return null;
52
+ }
53
+ return v;
54
+ };
35
55
  let i = 0;
36
56
  while (i < args.length) {
37
57
  const a = args[i];
@@ -44,6 +64,9 @@ export const parseArgs = (argv) => {
44
64
  case '-y':
45
65
  result.yes = true;
46
66
  break;
67
+ case '--bare':
68
+ result.bare = true;
69
+ break;
47
70
  case '--no-install':
48
71
  result.install = false;
49
72
  break;
@@ -54,15 +77,46 @@ export const parseArgs = (argv) => {
54
77
  result.git = false;
55
78
  break;
56
79
  case '--name': {
57
- const v = args[i + 1];
58
- if (v == null || v.startsWith('-')) {
59
- process.stderr.write('error: --name requires a value\n');
80
+ const v = value(i, '--name');
81
+ if (v == null)
60
82
  return null;
61
- }
62
83
  result.name = v;
63
84
  i++;
64
85
  break;
65
86
  }
87
+ case '--slug': {
88
+ const v = value(i, '--slug');
89
+ if (v == null)
90
+ return null;
91
+ if (!isValidSlug(v)) {
92
+ process.stderr.write(`error: --slug must match ${SLUG_PATTERN.source}`
93
+ + ' — lowercase letters, digits and inner dashes, 1-32 characters\n');
94
+ return null;
95
+ }
96
+ result.slug = v;
97
+ i++;
98
+ break;
99
+ }
100
+ case '--lang': {
101
+ const v = value(i, '--lang');
102
+ if (v == null)
103
+ return null;
104
+ if (!isValidLang(v)) {
105
+ process.stderr.write(`error: --lang must be a language code such as en or pt-BR\n`);
106
+ return null;
107
+ }
108
+ result.lang = v;
109
+ i++;
110
+ break;
111
+ }
112
+ case '--description': {
113
+ const v = value(i, '--description', true);
114
+ if (v == null)
115
+ return null;
116
+ result.description = v;
117
+ i++;
118
+ break;
119
+ }
66
120
  case '--pm': {
67
121
  const v = args[i + 1];
68
122
  if (v == null || !PMS.includes(v)) {
package/build/args.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
package/build/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  export { run } from './run.js';
2
2
  export { parseArgs, printHelp } from './args.js';
3
3
  export type { CreateArgs, PackageManager } from './args.js';
4
+ export { scaffold } from './scaffold.js';
5
+ export type { ScaffoldOptions } from './scaffold.js';
4
6
  export { copyTemplate, templateDir, isEmptyDir } from './template.js';
5
- export type { TemplateReplacements } from './template.js';
7
+ export type { BareManifest, CopyTemplateOptions, TemplateReplacements } from './template.js';
8
+ export { DEFAULT_LANG, defaultDescription, isValidLang, isValidSlug, LANG_PATTERN, SLUG_PATTERN, slugify, titleize } from './naming.js';
6
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAChD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AACrE,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAChD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AACrE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAC5F,OAAO,EACL,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAC1G,MAAM,aAAa,CAAA"}
package/build/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export { run } from './run.js';
2
2
  export { parseArgs, printHelp } from './args.js';
3
+ export { scaffold } from './scaffold.js';
3
4
  export { copyTemplate, templateDir, isEmptyDir } from './template.js';
5
+ export { DEFAULT_LANG, defaultDescription, isValidLang, isValidSlug, LANG_PATTERN, SLUG_PATTERN, slugify, titleize } from './naming.js';
4
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAEhD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAErE,OAAO,EACL,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAC1G,MAAM,aAAa,CAAA"}
@@ -0,0 +1,11 @@
1
+ /** npm-safe package slug: lowercase alphanumerics and inner dashes, 1–32 chars. */
2
+ export declare const SLUG_PATTERN: RegExp;
3
+ /** Loose BCP-47 shape — enough to keep junk out of `<html lang>` without shipping a registry. */
4
+ export declare const LANG_PATTERN: RegExp;
5
+ export declare const DEFAULT_LANG = "en";
6
+ export declare const isValidSlug: (slug: string) => boolean;
7
+ export declare const isValidLang: (lang: string) => boolean;
8
+ export declare const slugify: (input: string) => string;
9
+ export declare const titleize: (slug: string) => string;
10
+ export declare const defaultDescription: (name: string) => string;
11
+ //# sourceMappingURL=naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../src/naming.ts"],"names":[],"mappings":"AAEA,mFAAmF;AACnF,eAAO,MAAM,YAAY,QAA2C,CAAA;AAEpE,iGAAiG;AACjG,eAAO,MAAM,YAAY,QAA0C,CAAA;AAEnE,eAAO,MAAM,YAAY,OAAO,CAAA;AAEhC,eAAO,MAAM,WAAW,SAAU,MAAM,KAAG,OAAkC,CAAA;AAE7E,eAAO,MAAM,WAAW,SAAU,MAAM,KAAG,OAAkC,CAAA;AAE7E,eAAO,MAAM,OAAO,UAAW,MAAM,KAAG,MAOnB,CAAA;AAErB,eAAO,MAAM,QAAQ,SAAU,MAAM,KAAG,MAC6C,CAAA;AAErF,eAAO,MAAM,kBAAkB,SAAU,MAAM,KAAG,MACJ,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { basename } from 'node:path';
2
+ /** npm-safe package slug: lowercase alphanumerics and inner dashes, 1–32 chars. */
3
+ export const SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,30}[a-z0-9])?$/;
4
+ /** Loose BCP-47 shape — enough to keep junk out of `<html lang>` without shipping a registry. */
5
+ export const LANG_PATTERN = /^[a-zA-Z]{2,8}(?:-[a-zA-Z0-9]{1,8})*$/;
6
+ export const DEFAULT_LANG = 'en';
7
+ export const isValidSlug = (slug) => SLUG_PATTERN.test(slug);
8
+ export const isValidLang = (lang) => LANG_PATTERN.test(lang);
9
+ export const slugify = (input) => basename(input)
10
+ .toLowerCase()
11
+ .replace(/[^a-z0-9-]+/g, '-')
12
+ .replace(/^-+/g, '')
13
+ .slice(0, 32)
14
+ .replace(/-+$/g, '')
15
+ || 'owlmeans-app';
16
+ export const titleize = (slug) => slug.split('-').filter(Boolean).map(w => w[0].toUpperCase() + w.slice(1)).join(' ');
17
+ export const defaultDescription = (name) => `${name} — a fullstack OwlMeans Common app.`;
18
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../src/naming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEpC,mFAAmF;AACnF,MAAM,CAAC,MAAM,YAAY,GAAG,wCAAwC,CAAA;AAEpE,iGAAiG;AACjG,MAAM,CAAC,MAAM,YAAY,GAAG,uCAAuC,CAAA;AAEnE,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAA;AAEhC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAE7E,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAE7E,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAa,EAAU,EAAE,CAC/C,QAAQ,CAAC,KAAK,CAAC;KACZ,WAAW,EAAE;KACb,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;KAC5B,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;KACnB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;KACZ,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;OACjB,cAAc,CAAA;AAErB,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAU,EAAE,CAC/C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAErF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAU,EAAE,CACzD,GAAG,IAAI,qCAAqC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,WAAW,CAAA;AAiB3D,eAAO,MAAM,GAAG,SAAgB,UAAU,KAAG,OAAO,CAAC,MAAM,CA4E1D,CAAA"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,WAAW,CAAA;AAQ3D,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 { basename, resolve } from 'node:path';
2
+ import { resolve } from 'node:path';
3
3
  import { run as installSkills } from '@owlmeans/agent-skills';
4
+ import { defaultDescription, isValidSlug, slugify, titleize } from './naming.js';
4
5
  import { copyTemplate, isEmptyDir, templateDir } from './template.js';
5
- const slugify = (input) => basename(input)
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(' ');
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);
14
+ const slug = args.slug ?? slugify(args.dir);
15
+ if (!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
20
  const name = args.name ?? titleize(slug);
21
+ const description = args.description ?? defaultDescription(name);
21
22
  if (!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(' ✓ template copied (common + api + web)');
27
+ copyTemplate(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.12` 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.12\` later.\n`);
63
66
  }
64
67
  }
65
68
  catch (err) {
@@ -74,7 +77,10 @@ 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('Open the "Session" page to exercise the in-memory session resource.\n');
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');
78
84
  log('Agent guidance was scaffolded: AGENTS.md (with a CLAUDE.md bridge), 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');
package/build/run.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export interface ScaffoldOptions {
2
+ /** Destination directory. Created when missing; an existing one is written into as-is. */
3
+ dir: string;
4
+ /** package/workspace slug, e.g. `my-app`. */
5
+ slug: string;
6
+ /** Human-readable name. Defaults to the titleized slug. */
7
+ name?: string;
8
+ /** BCP-47-ish UI language and `<html lang>`. Defaults to `en`. */
9
+ lang?: string;
10
+ /** One-line description for the README, AGENTS.md and the index.html meta tags. */
11
+ description?: string;
12
+ /** Scaffold the shell without the example/demo code. */
13
+ bare?: boolean;
14
+ }
15
+ /**
16
+ * Filesystem-only scaffolding for tools that drive create-app themselves: no git, no
17
+ * dependency install, no agent-skills deploy, no output. Everything the CLI adds around
18
+ * the copy is the CLI's business — a caller that wants it calls `run` instead.
19
+ */
20
+ export declare const scaffold: (opts: ScaffoldOptions) => void;
21
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAIA,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;;;;GAIG;AACH,eAAO,MAAM,QAAQ,SAAU,eAAe,KAAG,IAShD,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { resolve } from 'node:path';
2
+ import { DEFAULT_LANG, defaultDescription, titleize } from './naming.js';
3
+ import { copyTemplate, templateDir } from './template.js';
4
+ /**
5
+ * Filesystem-only scaffolding for tools that drive create-app themselves: no git, no
6
+ * dependency install, no agent-skills deploy, no output. Everything the CLI adds around
7
+ * the copy is the CLI's business — a caller that wants it calls `run` instead.
8
+ */
9
+ export const scaffold = (opts) => {
10
+ const name = opts.name ?? titleize(opts.slug);
11
+ copyTemplate(templateDir(), resolve(opts.dir), {
12
+ slug: opts.slug,
13
+ name,
14
+ lang: opts.lang ?? DEFAULT_LANG,
15
+ description: opts.description ?? defaultDescription(name),
16
+ }, { bare: opts.bare === true });
17
+ };
18
+ //# 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,kBAAkB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAiBzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAqB,EAAQ,EAAE;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE7C,YAAY,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAC7C,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI;QACJ,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,YAAY;QAC/B,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,kBAAkB,CAAC,IAAI,CAAC;KAC1D,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,CAAA;AAClC,CAAC,CAAA"}
@@ -1,17 +1,33 @@
1
1
  import { renameSync } from 'node:fs';
2
+ export interface BareManifest {
3
+ /** Template-relative paths — a file, a directory subtree, or a `*` / `**` glob — the bare shell omits. */
4
+ remove: string[];
5
+ /** Target template path → the `.bare.`-infixed source whose CONTENT is written there instead. */
6
+ overrides: Record<string, string>;
7
+ }
2
8
  export interface TemplateReplacements {
3
9
  /** package/workspace slug, e.g. `my-app` */
4
10
  slug: string;
5
11
  /** human-readable name, e.g. `My App` */
6
12
  name: string;
13
+ /** BCP-47-ish UI language, e.g. `en` — also the generated `<html lang>` */
14
+ lang: string;
15
+ /** one-line project description for the README, AGENTS.md and the index.html meta tags */
16
+ description: string;
17
+ }
18
+ export interface CopyTemplateOptions {
19
+ /** Scaffold the demo-free shell: apply `_bare.json`'s removals and overrides. */
20
+ bare?: boolean;
7
21
  }
8
22
  /** Absolute path to the bundled `template/` directory (sibling of `build/`). */
9
23
  export declare const templateDir: () => string;
10
24
  /**
11
- * Recursively copy `src` → `dest`, substituting `__APP_SLUG__` / `__APP_NAME__`
12
- * in text files and renaming shipped dotfiles (`_gitignore` → `.gitignore`).
25
+ * Recursively copy `src` → `dest`, substituting the `__APP_*__` placeholders in text files
26
+ * and renaming shipped dotfiles (`_gitignore` → `.gitignore`). With `bare` the template's
27
+ * `_bare.json` decides what is dropped and which `.bare.` variant supplies the content, so
28
+ * the demo inventory lives in the template rather than in this code.
13
29
  */
14
- export declare const copyTemplate: (src: string, dest: string, r: TemplateReplacements) => void;
30
+ export declare const copyTemplate: (src: string, dest: string, r: TemplateReplacements, opts?: CopyTemplateOptions) => void;
15
31
  export declare const isEmptyDir: (dir: string) => boolean;
16
32
  export { renameSync };
17
33
  //# sourceMappingURL=template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4D,UAAU,EAA2B,MAAM,SAAS,CAAA;AAsBvH,MAAM,WAAW,oBAAoB;IACnC,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAA;IACZ,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;CACb;AAED,gFAAgF;AAChF,eAAO,MAAM,WAAW,QAAO,MACqC,CAAA;AAYpE;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAS,MAAM,QAAQ,MAAM,KAAK,oBAAoB,KAAG,IAoBjF,CAAA;AAED,eAAO,MAAM,UAAU,QAAS,MAAM,KAAG,OAGxC,CAAA;AAED,OAAO,EAAE,UAAU,EAAE,CAAA"}
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4D,UAAU,EAA2B,MAAM,SAAS,CAAA;AAyBvH,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;AAED,gFAAgF;AAChF,eAAO,MAAM,WAAW,QAAO,MACqC,CAAA;AAiFpE;;;;;GAKG;AACH,eAAO,MAAM,YAAY,QAClB,MAAM,QAAQ,MAAM,KAAK,oBAAoB,SAAQ,mBAAmB,KAC5E,IAEF,CAAA;AAED,eAAO,MAAM,UAAU,QAAS,MAAM,KAAG,OAGxC,CAAA;AAED,OAAO,EAAE,UAAU,EAAE,CAAA"}
package/build/template.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync } from 'node:fs';
2
2
  import { fileURLToPath } from 'node:url';
3
- import { dirname, join, resolve } from 'node:path';
3
+ import { dirname, join, relative, resolve, sep } from 'node:path';
4
4
  /** Dotfiles/dirs are shipped with an underscore prefix so npm does not strip them from the tarball. */
5
5
  const DOTFILE_RENAMES = {
6
6
  '_gitignore': '.gitignore',
@@ -17,37 +17,77 @@ const DOTFILE_RENAMES = {
17
17
  };
18
18
  /** Files whose contents are binary or must not be string-substituted. */
19
19
  const BINARY_EXT = new Set(['.ico', '.png', '.jpg', '.jpeg', '.gif', '.webp', '.woff', '.woff2']);
20
+ /** Template-root manifest describing what the bare shell drops and what it swaps in. */
21
+ const BARE_MANIFEST = '_bare.json';
20
22
  /** Absolute path to the bundled `template/` directory (sibling of `build/`). */
21
23
  export const templateDir = () => resolve(dirname(fileURLToPath(import.meta.url)), '..', 'template');
22
24
  const applyReplacements = (content, r) => content
23
25
  .replaceAll('__APP_SLUG__', r.slug)
24
- .replaceAll('__APP_NAME__', r.name);
26
+ .replaceAll('__APP_NAME__', r.name)
27
+ .replaceAll('__APP_LANG__', r.lang)
28
+ .replaceAll('__APP_DESCRIPTION__', r.description);
25
29
  const isBinary = (file) => {
26
30
  const dot = file.lastIndexOf('.');
27
31
  return dot >= 0 && BINARY_EXT.has(file.slice(dot).toLowerCase());
28
32
  };
29
33
  /**
30
- * Recursively copy `src` `dest`, substituting `__APP_SLUG__` / `__APP_NAME__`
31
- * in text files and renaming shipped dotfiles (`_gitignore` `.gitignore`).
34
+ * Bare variants sit beside the files they replace so the normal template still compiles as
35
+ * one project which is also why they are filtered out of the copy in BOTH modes.
32
36
  */
33
- export const copyTemplate = (src, dest, r) => {
37
+ const isBareVariant = (entry) => entry.includes('.bare.');
38
+ /** Stand-in for the globstar segment while the single-`*` pass runs; cannot occur in a path. */
39
+ const GLOBSTAR = '\u0000';
40
+ const globToRegExp = (pattern) => new RegExp('^' + pattern
41
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
42
+ .replaceAll('**/', GLOBSTAR)
43
+ .replace(/\*/g, '[^/]*')
44
+ .replaceAll(GLOBSTAR, '(?:.*/)?')
45
+ + '$');
46
+ const isRemoved = (rel, patterns) => patterns.some(pattern => rel === pattern
47
+ // A directory pattern takes its whole subtree — the walk simply never descends into it.
48
+ || rel.startsWith(pattern.endsWith('/') ? pattern : pattern + '/')
49
+ || (pattern.includes('*') && globToRegExp(pattern).test(rel)));
50
+ const readBareManifest = (root) => {
51
+ const file = join(root, BARE_MANIFEST);
52
+ if (!existsSync(file)) {
53
+ throw new Error(`bare scaffolding requires ${BARE_MANIFEST} in the template (${root})`);
54
+ }
55
+ const parsed = JSON.parse(readFileSync(file, 'utf8'));
56
+ return { remove: parsed.remove ?? [], overrides: parsed.overrides ?? {} };
57
+ };
58
+ const toPosix = (path) => path.split(sep).join('/');
59
+ const copyTree = (src, dest, r, root, bare) => {
34
60
  mkdirSync(dest, { recursive: true });
35
61
  for (const entry of readdirSync(src)) {
36
62
  const from = join(src, entry);
37
- const targetName = DOTFILE_RENAMES[entry] ?? entry;
38
- const to = join(dest, targetName);
63
+ const rel = toPosix(relative(root, from));
64
+ if (rel === BARE_MANIFEST || isBareVariant(entry))
65
+ continue;
66
+ if (bare != null && isRemoved(rel, bare.remove))
67
+ continue;
68
+ const to = join(dest, DOTFILE_RENAMES[entry] ?? entry);
39
69
  if (statSync(from).isDirectory()) {
40
- copyTemplate(from, to, r);
70
+ copyTree(from, to, r, root, bare);
41
71
  continue;
42
72
  }
43
- if (isBinary(from)) {
44
- cpSync(from, to);
73
+ const override = bare?.overrides[rel];
74
+ const source = override != null ? join(root, override) : from;
75
+ if (isBinary(source)) {
76
+ cpSync(source, to);
45
77
  continue;
46
78
  }
47
- const content = applyReplacements(readFileSync(from, 'utf8'), r);
48
- writeFileSync(to, content);
79
+ writeFileSync(to, applyReplacements(readFileSync(source, 'utf8'), r));
49
80
  }
50
81
  };
82
+ /**
83
+ * Recursively copy `src` → `dest`, substituting the `__APP_*__` placeholders in text files
84
+ * and renaming shipped dotfiles (`_gitignore` → `.gitignore`). With `bare` the template's
85
+ * `_bare.json` decides what is dropped and which `.bare.` variant supplies the content, so
86
+ * the demo inventory lives in the template rather than in this code.
87
+ */
88
+ export const copyTemplate = (src, dest, r, opts = {}) => {
89
+ copyTree(src, dest, r, src, opts.bare === true ? readBareManifest(src) : null);
90
+ };
51
91
  export const isEmptyDir = (dir) => {
52
92
  if (!existsSync(dir))
53
93
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"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"}
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,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAEjE,uGAAuG;AACvG,MAAM,eAAe,GAA2B;IAC9C,YAAY,EAAE,YAAY;IAC1B,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,MAAM;IACd,SAAS,EAAE,SAAS;IACpB,kFAAkF;IAClF,+EAA+E;IAC/E,kFAAkF;IAClF,6EAA6E;IAC7E,oBAAoB;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;CACrB,CAAA;AAED,yEAAyE;AACzE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;AAEjG,wFAAwF;AACxF,MAAM,aAAa,GAAG,YAAY,CAAA;AAyBlC,gFAAgF;AAChF,MAAM,CAAC,MAAM,WAAW,GAAG,GAAW,EAAE,CACtC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAA;AAEpE,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAE,CAAuB,EAAU,EAAE,CAC7E,OAAO;KACJ,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC;KAClC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC;KAClC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC;KAClC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC,WAAW,CAAC,CAAA;AAErD,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAW,EAAE;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IACjC,OAAO,GAAG,IAAI,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;AAClE,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,aAAa,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AAE1E,gGAAgG;AAChG,MAAM,QAAQ,GAAG,QAAQ,CAAA;AAEzB,MAAM,YAAY,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,IAAI,MAAM,CAC1D,GAAG,GAAG,OAAO;KACV,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC;KACpC,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC;KAC3B,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;KACvB,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC;MACjC,GAAG,CACN,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,QAAkB,EAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CACtF,GAAG,KAAK,OAAO;IACf,wFAAwF;OACrF,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC;OAC/D,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAC9D,CAAA;AAED,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAgB,EAAE;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;IACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,6BAA6B,aAAa,qBAAqB,IAAI,GAAG,CAAC,CAAA;IACzF,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAA0B,CAAA;IAE9E,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,CAAA;AAC3E,CAAC,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAEnE,MAAM,QAAQ,GAAG,CACf,GAAW,EAAE,IAAY,EAAE,CAAuB,EAAE,IAAY,EAAE,IAAyB,EACrF,EAAE;IACR,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACpC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;QAEzC,IAAI,GAAG,KAAK,aAAa,IAAI,aAAa,CAAC,KAAK,CAAC;YAAE,SAAQ;QAC3D,IAAI,IAAI,IAAI,IAAI,IAAI,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC;YAAE,SAAQ;QAEzD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAA;QAEtD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACjC,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;YACjC,SAAQ;QACV,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,MAAM,GAAG,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAE7D,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;YAClB,SAAQ;QACV,CAAC;QAED,aAAa,CAAC,EAAE,EAAE,iBAAiB,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACvE,CAAC;AACH,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,GAAW,EAAE,IAAY,EAAE,CAAuB,EAAE,IAAI,GAAwB,EAAE,EAC5E,EAAE;IACR,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AAChF,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAW,EAAE;IACjD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACjC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAA;AACtC,CAAC,CAAA;AAED,OAAO,EAAE,UAAU,EAAE,CAAA"}
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@owlmeans/create-app",
3
- "version": "0.1.18-rc.2",
3
+ "version": "0.1.18-rc.20",
4
4
  "license": "MIT",
5
- "description": "Scaffold a minimal fullstack OwlMeans Common app — common + api + web workspaces, shadcn UI navigation/layout, no auth, and a session-scoped in-memory resource. Deploys agent skills via @owlmeans/agent-skills by default.",
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,7 +30,7 @@
29
30
  "template"
30
31
  ],
31
32
  "dependencies": {
32
- "@owlmeans/agent-skills": "^0.1.18-rc.2"
33
+ "@owlmeans/agent-skills": "^0.1.18-rc.16"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@owlmeans/dep-config": "workspace:*",