@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.
Files changed (115) hide show
  1. package/README.md +49 -5
  2. package/build/args/types.d.ts +9 -0
  3. package/build/args/types.d.ts.map +1 -0
  4. package/build/args/types.js +2 -0
  5. package/build/args/types.js.map +1 -0
  6. package/build/args.d.ts +3 -20
  7. package/build/args.d.ts.map +1 -1
  8. package/build/args.js +121 -88
  9. package/build/args.js.map +1 -1
  10. package/build/bin.js +3 -3
  11. package/build/bin.js.map +1 -1
  12. package/build/consts.d.ts +6 -0
  13. package/build/consts.d.ts.map +1 -0
  14. package/build/consts.js +6 -0
  15. package/build/consts.js.map +1 -0
  16. package/build/consts.local.d.ts +12 -0
  17. package/build/consts.local.d.ts.map +1 -0
  18. package/build/consts.local.js +49 -0
  19. package/build/consts.local.js.map +1 -0
  20. package/build/index.d.ts +11 -4
  21. package/build/index.d.ts.map +1 -1
  22. package/build/index.js +5 -2
  23. package/build/index.js.map +1 -1
  24. package/build/naming/types.d.ts +14 -0
  25. package/build/naming/types.d.ts.map +1 -0
  26. package/build/naming/types.js +2 -0
  27. package/build/naming/types.js.map +1 -0
  28. package/build/naming.d.ts +4 -0
  29. package/build/naming.d.ts.map +1 -0
  30. package/build/naming.js +18 -0
  31. package/build/naming.js.map +1 -0
  32. package/build/run.d.ts +1 -1
  33. package/build/run.d.ts.map +1 -1
  34. package/build/run.js +23 -17
  35. package/build/run.js.map +1 -1
  36. package/build/scaffold.d.ts +8 -0
  37. package/build/scaffold.d.ts.map +1 -0
  38. package/build/scaffold.js +19 -0
  39. package/build/scaffold.js.map +1 -0
  40. package/build/template/types.d.ts +16 -0
  41. package/build/template/types.d.ts.map +1 -0
  42. package/build/template/types.js +2 -0
  43. package/build/template/types.js.map +1 -0
  44. package/build/template.d.ts +3 -16
  45. package/build/template.d.ts.map +1 -1
  46. package/build/template.js +69 -52
  47. package/build/template.js.map +1 -1
  48. package/build/types.d.ts +61 -0
  49. package/build/types.d.ts.map +1 -0
  50. package/build/types.js +2 -0
  51. package/build/types.js.map +1 -0
  52. package/package.json +5 -4
  53. package/template/AGENTS.md +61 -2
  54. package/template/README.bare.md +70 -0
  55. package/template/README.md +9 -60
  56. package/template/_agents/scripts/link-skills.sh +327 -15
  57. package/template/_agents/skills/agent-memory/SKILL.md +12 -11
  58. package/template/_agents/skills/getting-started/SKILL.md +38 -79
  59. package/template/_agents/skills/logging/SKILL.md +38 -0
  60. package/template/_agents/skills/memory-promotion/SKILL.md +10 -4
  61. package/template/_agents/skills/memory-recompact/SKILL.md +15 -14
  62. package/template/_agents/skills/owlmeans-code-structure/SKILL.md +182 -0
  63. package/template/_agents/skills/reuse-code/SKILL.md +56 -10
  64. package/template/_agents/skills/self-education/SKILL.md +25 -5
  65. package/template/_agents/skills/skill-authoring/SKILL.md +78 -12
  66. package/template/_bare.json +24 -0
  67. package/template/_gitignore +8 -0
  68. package/template/bunfig.toml +2 -0
  69. package/template/package.json +3 -2
  70. package/template/sources/api/package.json +5 -4
  71. package/template/sources/api/src/app/session/add.ts +6 -17
  72. package/template/sources/api/src/app/session/list.ts +6 -12
  73. package/template/sources/api/src/app/session/remove.ts +6 -15
  74. package/template/sources/api/src/config.ts +7 -0
  75. package/template/sources/api/src/context.bare.ts +11 -0
  76. package/template/sources/api/src/entrypoints.bare.ts +4 -0
  77. package/template/sources/api/src/entrypoints.ts +13 -0
  78. package/template/sources/api/src/index.ts +8 -2
  79. package/template/sources/api/src/models/session/types.ts +14 -0
  80. package/template/sources/api/src/models/session.ts +43 -0
  81. package/template/sources/api/src/types.bare.ts +5 -0
  82. package/template/sources/common/package.json +8 -8
  83. package/template/sources/common/src/config.ts +2 -1
  84. package/template/sources/common/src/consts.bare.ts +8 -0
  85. package/template/sources/common/src/consts.ts +0 -13
  86. package/template/sources/common/src/entrypoints.bare.ts +14 -0
  87. package/template/sources/common/src/entrypoints.ts +60 -0
  88. package/template/sources/common/src/index.bare.ts +3 -0
  89. package/template/sources/common/src/index.ts +1 -1
  90. package/template/sources/common/src/schemas.ts +7 -7
  91. package/template/sources/web/index.html +3 -1
  92. package/template/sources/web/package.json +33 -30
  93. package/template/sources/web/src/components/ui/dropdown-menu.tsx +257 -0
  94. package/template/sources/web/src/components/ui/navigation-menu.tsx +169 -0
  95. package/template/sources/web/src/config.ts +8 -0
  96. package/template/sources/web/src/consts.ts +14 -0
  97. package/template/sources/web/src/context.bare.ts +13 -0
  98. package/template/sources/web/src/context.ts +12 -2
  99. package/template/sources/web/src/entrypoints.bare.ts +13 -0
  100. package/template/sources/web/src/entrypoints.ts +16 -0
  101. package/template/sources/web/src/index.css +7 -0
  102. package/template/sources/web/src/index.tsx +2 -2
  103. package/template/sources/web/src/layout/main.tsx +17 -19
  104. package/template/sources/web/src/nav.bare.ts +23 -0
  105. package/template/sources/web/src/nav.ts +23 -0
  106. package/template/sources/web/src/screens/about.tsx +19 -0
  107. package/template/sources/web/src/screens/home.bare.tsx +17 -0
  108. package/template/sources/web/src/screens/session.tsx +30 -17
  109. package/template/sources/web/src/vite-env.d.ts +8 -0
  110. package/template/sources/web/vite.config.ts +3 -2
  111. package/template/CLAUDE.md +0 -13
  112. package/template/sources/api/src/modules.ts +0 -11
  113. package/template/sources/common/src/modules.ts +0 -26
  114. package/template/sources/web/src/components/nav/main.tsx +0 -15
  115. package/template/sources/web/src/modules.ts +0 -20
@@ -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,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 { basename, resolve } from 'node:path';
2
+ import { resolve } from 'node:path';
3
3
  import { run as installSkills } from '@owlmeans/agent-skills';
4
- 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(' ');
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
- const name = args.name ?? titleize(slug);
21
- if (!isEmptyDir(dest) && !args.yes) {
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(' ✓ template copied (common + api + web)');
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('Open the "Session" page to exercise the in-memory session resource.\n');
78
- log('Agent guidance was scaffolded: AGENTS.md (with a CLAUDE.md bridge), the skills in');
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":"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"}
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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/template/types.ts"],"names":[],"mappings":""}
@@ -1,17 +1,4 @@
1
- import { renameSync } from 'node:fs';
2
- export interface TemplateReplacements {
3
- /** package/workspace slug, e.g. `my-app` */
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
@@ -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":"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, renameSync, statSync, writeFileSync } from 'node:fs';
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
- /** Dotfiles/dirs are shipped with an underscore prefix so npm does not strip them from the tarball. */
5
- const DOTFILE_RENAMES = {
6
- '_gitignore': '.gitignore',
7
- '_npmrc': '.npmrc',
8
- '_env': '.env',
9
- '_github': '.github',
10
- // `_agents` carries the canonical harness — AGENTS.md's skills, the shared memory
11
- // store and the link-skills bridge; the template seed (sync-agent-meta) writes
12
- // `_agents/skills/` into this tree. `_claude` carries only the Claude Code bridge
13
- // (SessionStart hook + the gitkept symlink dir). Entries whose source dir is
14
- // absent are inert.
15
- '_agents': '.agents',
16
- '_claude': '.claude',
17
- };
18
- /** Files whose contents are binary or must not be string-substituted. */
19
- const BINARY_EXT = new Set(['.ico', '.png', '.jpg', '.jpeg', '.gif', '.webp', '.woff', '.woff2']);
20
- /** Absolute path to the bundled `template/` directory (sibling of `build/`). */
21
- export const templateDir = () => resolve(dirname(fileURLToPath(import.meta.url)), '..', 'template');
22
- const applyReplacements = (content, r) => content
23
- .replaceAll('__APP_SLUG__', r.slug)
24
- .replaceAll('__APP_NAME__', r.name);
25
- const isBinary = (file) => {
26
- const dot = file.lastIndexOf('.');
27
- return dot >= 0 && BINARY_EXT.has(file.slice(dot).toLowerCase());
28
- };
29
- /**
30
- * Recursively copy `src` → `dest`, substituting `__APP_SLUG__` / `__APP_NAME__`
31
- * in text files and renaming shipped dotfiles (`_gitignore` → `.gitignore`).
32
- */
33
- export const copyTemplate = (src, dest, r) => {
34
- mkdirSync(dest, { recursive: true });
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
- if (isBinary(from)) {
44
- cpSync(from, to);
45
- continue;
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
- const content = applyReplacements(readFileSync(from, 'utf8'), r);
48
- writeFileSync(to, content);
49
- }
50
- };
51
- export const isEmptyDir = (dir) => {
52
- if (!existsSync(dir))
53
- return true;
54
- return readdirSync(dir).length === 0;
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 { renameSync };
73
+ export const templateHelper = createTemplateHelper();
57
74
  //# sourceMappingURL=template.js.map
@@ -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,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC3G,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAIxF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAmB,EAAE;IACvD,MAAM,WAAW,GAAG,GAAW,EAAE,CAC/B,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAA;IAEpE,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAE,CAAuB,EAAU,EAAE,CAC7E,OAAO;SACJ,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC;SAClC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC;SAClC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC;SAClC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC,WAAW,CAAC,CAAA;IAErD,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAW,EAAE;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;QACjC,OAAO,GAAG,IAAI,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;IAClE,CAAC,CAAA;IAED;;;OAGG;IACH,MAAM,aAAa,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAE1E,MAAM,YAAY,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,IAAI,MAAM,CAC1D,GAAG,GAAG,OAAO;SACV,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC;SACpC,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC;SAC3B,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC;UACjC,GAAG,CACN,CAAA;IAED,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,QAAkB,EAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CACtF,GAAG,KAAK,OAAO;QACf,wFAAwF;WACrF,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC;WAC/D,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAC9D,CAAA;IAED,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAgB,EAAE;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,6BAA6B,aAAa,qBAAqB,IAAI,GAAG,CAAC,CAAA;QACzF,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAA0B,CAAA;QAE9E,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,CAAA;IAC3E,CAAC,CAAA;IAED,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAEnE,MAAM,QAAQ,GAAG,CACf,GAAW,EAAE,IAAY,EAAE,CAAuB,EAAE,IAAY,EAAE,IAAyB,EACrF,EAAE;QACR,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACpC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;YAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;YAEzC,IAAI,GAAG,KAAK,aAAa,IAAI,aAAa,CAAC,KAAK,CAAC;gBAAE,SAAQ;YAC3D,IAAI,IAAI,IAAI,IAAI,IAAI,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC;gBAAE,SAAQ;YAEzD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAA;YAEtD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;gBACjC,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;gBACjC,SAAQ;YACV,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,MAAM,GAAG,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;YAE7D,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrB,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;gBAClB,SAAQ;YACV,CAAC;YAED,aAAa,CAAC,EAAE,EAAE,iBAAiB,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACvE,CAAC;IACH,CAAC,CAAA;IAED,MAAM,YAAY,GAAG,CACnB,GAAW,EAAE,IAAY,EAAE,CAAuB,EAAE,IAAI,GAAwB,EAAE,EAC5E,EAAE;QACR,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;IAChF,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,CAAC,GAAW,EAAW,EAAE;QAC1C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;QACjC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAA;IACtC,CAAC,CAAA;IAED,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,CAAA;AAClD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAA"}
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -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.6",
3
+ "version": "0.1.18-rc.60",
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,11 +30,11 @@
29
30
  "template"
30
31
  ],
31
32
  "dependencies": {
32
- "@owlmeans/agent-skills": "^0.1.18-rc.6"
33
+ "@owlmeans/agent-skills": "^0.1.18-rc.51"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@owlmeans/dep-config": "workspace:*",
36
- "@types/node": "^26.1.0",
37
+ "@types/node": "^26.6.4",
37
38
  "nodemon": "^3.1.14",
38
39
  "typescript": "^7.0.2"
39
40
  },
@@ -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 `CLAUDE.md`).
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