@powerhousedao/ph-clint-cli 0.1.0-dev.52 → 0.1.0-dev.54

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 (37) hide show
  1. package/dist/cli.js +3 -2
  2. package/dist/codegen/actions.d.ts +1 -46
  3. package/dist/codegen/actions.js +1 -424
  4. package/dist/codegen/builders/app-index-ts.js +24 -20
  5. package/dist/codegen/builders/cli-package-json.d.ts +1 -8
  6. package/dist/codegen/builders/cli-package-json.js +1 -128
  7. package/dist/codegen/builders/index.d.ts +1 -51
  8. package/dist/codegen/builders/index.js +1 -84
  9. package/dist/codegen/exec.d.ts +1 -2
  10. package/dist/codegen/exec.js +1 -14
  11. package/dist/codegen/generated.d.ts +1 -17
  12. package/dist/codegen/generated.js +1 -49
  13. package/dist/codegen/hashes.d.ts +1 -6
  14. package/dist/codegen/hashes.js +1 -60
  15. package/dist/codegen/index.d.ts +8 -39
  16. package/dist/codegen/index.js +6 -407
  17. package/dist/codegen/markers.d.ts +1 -36
  18. package/dist/codegen/markers.js +1 -86
  19. package/dist/codegen/scaffold.d.ts +1 -72
  20. package/dist/codegen/scaffold.js +1 -150
  21. package/dist/codegen/write.d.ts +1 -6
  22. package/dist/codegen/write.js +1 -32
  23. package/dist/commands/clint-project-init.js +2 -2
  24. package/dist/commands/clint-project-regen.js +1 -1
  25. package/dist/commands/clint-skills-sync.d.ts +1 -1
  26. package/dist/commands/clint-skills-sync.js +1 -1
  27. package/dist/framework.js +1 -1
  28. package/dist/skills/sync.d.ts +1 -40
  29. package/dist/skills/sync.js +1 -119
  30. package/dist/spec/ensure-document.js +9 -15
  31. package/dist/spec/file.d.ts +1 -4
  32. package/dist/spec/file.js +1 -34
  33. package/dist/spec/types.d.ts +1 -164
  34. package/dist/spec/types.js +1 -209
  35. package/dist/triggers/publish-trigger.js +1 -1
  36. package/dist/triggers/spec-change.js +7 -1
  37. package/package.json +9 -9
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@
7
7
  * Everything outside the markers is user-editable and preserved.
8
8
  */
9
9
  import path from 'node:path';
10
- import { defineCli, buildDefaultReactor } from '@powerhousedao/ph-clint';
10
+ import { defineCli, buildDefaultReactor, deterministicId } from '@powerhousedao/ph-clint';
11
11
  import { z } from 'zod';
12
12
  import { CLI_NAME, CLI_VERSION, CLI_ROOT } from './config.js';
13
13
  import { configSchema, secretsSchema } from './framework.js';
@@ -38,6 +38,7 @@ export const cli = defineCli({
38
38
  // @clint:end services
39
39
  // @clint:begin triggers
40
40
  triggers: [specChangeTrigger, publishTrigger],
41
+ routine: { id: 'triggers', name: 'Triggers' },
41
42
  // @clint:end triggers
42
43
  // @clint:begin prompts
43
44
  prompts: {
@@ -108,7 +109,7 @@ cli.configureReactor({
108
109
  create: (ctx) => buildDefaultReactor(ctx, {
109
110
  documentModels,
110
111
  drives: [
111
- { name: 'Clint Folders', role: 'personal' },
112
+ { name: 'Clint Folders', role: 'personal', id: deterministicId(CLI_NAME, 'personal-drive') },
112
113
  ],
113
114
  subscriptions: { documentTypes: ['powerhouse/ph-clint-project'] },
114
115
  }),
@@ -1,46 +1 @@
1
- import type { GenerateProjectResult } from './index.js';
2
- import type { ClintProjectSpec, ExternalSkill } from '../spec/types.js';
3
- import type { ProcessRunOptions } from '@powerhousedao/ph-clint';
4
- export type PostGenAction = {
5
- kind: 'ph-init';
6
- targetDir: string;
7
- appDir: string;
8
- spec: ClintProjectSpec;
9
- } | {
10
- kind: 'app-install';
11
- dir: string;
12
- } | {
13
- kind: 'app-ph-install';
14
- appDir: string;
15
- packages: string[];
16
- } | {
17
- kind: 'app-build';
18
- dir: string;
19
- } | {
20
- kind: 'cli-install';
21
- dir: string;
22
- } | {
23
- kind: 'cli-build';
24
- dir: string;
25
- } | {
26
- kind: 'skills-sync';
27
- targetDir: string;
28
- desired: ExternalSkill[];
29
- };
30
- export type PostGenActionKind = PostGenAction['kind'];
31
- export interface PostGenActionContext {
32
- log: (msg: string) => void;
33
- runProcess: (command: string, opts?: Omit<ProcessRunOptions, 'onOutput'>) => Promise<{
34
- success: boolean;
35
- output: string;
36
- }>;
37
- skip?: Set<PostGenActionKind>;
38
- }
39
- export interface PostGenActionResult {
40
- action: PostGenAction;
41
- status: 'success' | 'failed' | 'skipped';
42
- reason?: string;
43
- durationMs: number;
44
- }
45
- export declare function collectPostGenActions(result: GenerateProjectResult, spec: ClintProjectSpec): Promise<PostGenAction[]>;
46
- export declare function runPostGenActions(actions: PostGenAction[], ctx: PostGenActionContext): Promise<PostGenActionResult[]>;
1
+ export { type PostGenAction, type PostGenActionKind, type PostGenActionContext, type PostGenActionResult, collectPostGenActions, runPostGenActions, } from '@powerhousedao/ph-clint-dev/codegen/actions';
@@ -1,424 +1 @@
1
- /**
2
- * Post-generation actions — a typed pipeline that runs after codegen.
3
- *
4
- * `collectPostGenActions()` inspects a `GenerateProjectResult` to determine
5
- * which side-effects (install, build, ph-init, skills-sync) are needed.
6
- *
7
- * `runPostGenActions()` executes them sequentially with proper ordering,
8
- * failure cascading, and log output.
9
- */
10
- import fs from 'node:fs/promises';
11
- import path from 'node:path';
12
- import { getAppPackageName } from '../spec/types.js';
13
- // ---------------------------------------------------------------------------
14
- // Fixed execution order — index defines precedence
15
- // ---------------------------------------------------------------------------
16
- const ACTION_ORDER = [
17
- 'ph-init',
18
- 'app-install',
19
- 'app-ph-install',
20
- 'app-build',
21
- 'cli-install',
22
- 'cli-build',
23
- 'skills-sync',
24
- ];
25
- function actionIndex(kind) {
26
- return ACTION_ORDER.indexOf(kind);
27
- }
28
- // ---------------------------------------------------------------------------
29
- // Dependency map — which actions depend on which (for failure cascading)
30
- // ---------------------------------------------------------------------------
31
- /** Returns true if `downstream` depends on `upstream` succeeding. */
32
- function dependsOn(downstream, upstream) {
33
- // ph-init → app-install → app-ph-install → app-build → cli-install → cli-build
34
- // skills-sync is independent of the build chain
35
- const chain = [
36
- 'ph-init',
37
- 'app-install',
38
- 'app-ph-install',
39
- 'app-build',
40
- 'cli-install',
41
- 'cli-build',
42
- ];
43
- if (downstream === 'skills-sync')
44
- return false;
45
- const di = chain.indexOf(downstream);
46
- const ui = chain.indexOf(upstream);
47
- if (di < 0 || ui < 0)
48
- return false;
49
- return di > ui;
50
- }
51
- // ---------------------------------------------------------------------------
52
- // Helpers
53
- // ---------------------------------------------------------------------------
54
- async function fileExists(filePath) {
55
- try {
56
- await fs.access(filePath);
57
- return true;
58
- }
59
- catch {
60
- return false;
61
- }
62
- }
63
- /** External packages that have document types (not the app package). */
64
- function getExternalPackages(spec) {
65
- const appPkg = getAppPackageName(spec);
66
- return spec.packages.filter((p) => p.packageName !== appPkg && p.documentTypes.length > 0);
67
- }
68
- /**
69
- * Returns package names from `extPkgs` that are not yet registered in
70
- * the app's `powerhouse.config.json`.
71
- */
72
- async function getMissingPhPackages(appDir, extPkgs) {
73
- try {
74
- const raw = await fs.readFile(path.join(appDir, 'powerhouse.config.json'), 'utf8');
75
- const config = JSON.parse(raw);
76
- const registered = new Set((config.packages ?? []).map((p) => p.packageName));
77
- return extPkgs
78
- .map((p) => p.packageName)
79
- .filter((name) => !registered.has(name));
80
- }
81
- catch {
82
- // No config file yet (pre-init) — all packages are missing
83
- return extPkgs.map((p) => p.packageName);
84
- }
85
- }
86
- // ---------------------------------------------------------------------------
87
- // collectPostGenActions
88
- // ---------------------------------------------------------------------------
89
- export async function collectPostGenActions(result, spec) {
90
- const split = result.appDir !== null;
91
- const relPaths = new Set(result.files.map((f) => f.relativePath));
92
- // Determine the earliest triggered action in the chain
93
- let earliest = null;
94
- if (split) {
95
- const appFolder = result.appDir ? path.basename(result.appDir) : '';
96
- const cliFolder = path.basename(result.cliDir);
97
- // ph-init needed: app dir placeholder written but app not yet initialized.
98
- // Check the actual filesystem — if package.json already exists on disk,
99
- // ph init has already run and must not run again.
100
- const appPkgJsonChanged = relPaths.has(path.join(appFolder, 'package.json'));
101
- const appGitkeepWritten = relPaths.has(path.join(appFolder, '.gitkeep'));
102
- // ph-init needed: app dir placeholder written but app not yet initialized.
103
- // Check the actual filesystem — if package.json already exists on disk,
104
- // ph init has already run and must not run again.
105
- if (appGitkeepWritten && !appPkgJsonChanged) {
106
- const appAlreadyInitialized = result.appDir
107
- ? await fileExists(path.join(result.appDir, 'package.json'))
108
- : false;
109
- if (!appAlreadyInitialized) {
110
- earliest = 'ph-init';
111
- }
112
- }
113
- // Migration always triggers full rebuild
114
- if (result.migrated) {
115
- earliest = earliest ?? 'app-install';
116
- }
117
- // App package.json changed
118
- if (!earliest && appPkgJsonChanged) {
119
- earliest = 'app-install';
120
- }
121
- // App source regenerated (framework.gen.ts, index.ts, etc.)
122
- if (!earliest) {
123
- for (const rel of relPaths) {
124
- if (rel.startsWith(appFolder + '/') &&
125
- rel.endsWith('.ts')) {
126
- earliest = 'app-build';
127
- break;
128
- }
129
- }
130
- }
131
- // CLI package.json changed
132
- if (!earliest) {
133
- if (relPaths.has(path.join(cliFolder, 'package.json'))) {
134
- earliest = 'cli-install';
135
- }
136
- }
137
- // CLI source or prompts regenerated (.ts files, agent profile .md files)
138
- if (!earliest) {
139
- for (const rel of relPaths) {
140
- if (rel.startsWith(cliFolder + '/') &&
141
- (rel.endsWith('.ts') || rel.endsWith('.md'))) {
142
- earliest = 'cli-build';
143
- break;
144
- }
145
- }
146
- }
147
- }
148
- else {
149
- // Flat layout
150
- if (relPaths.has('package.json')) {
151
- earliest = 'cli-install';
152
- }
153
- else {
154
- for (const rel of relPaths) {
155
- if (rel.endsWith('.ts') || rel.endsWith('.md')) {
156
- earliest = 'cli-build';
157
- break;
158
- }
159
- }
160
- }
161
- }
162
- // Check if external packages need registering in the app
163
- const extPkgs = split && result.appDir ? getExternalPackages(spec) : [];
164
- if (split && result.appDir && extPkgs.length > 0) {
165
- const missing = await getMissingPhPackages(result.appDir, extPkgs);
166
- if (missing.length > 0) {
167
- if (!earliest || actionIndex(earliest) > actionIndex('app-ph-install')) {
168
- earliest = 'app-ph-install';
169
- }
170
- }
171
- }
172
- // Build the action list from earliest onward
173
- const actions = [];
174
- if (earliest && split && result.appDir) {
175
- const ei = actionIndex(earliest);
176
- if (ei <= actionIndex('ph-init')) {
177
- actions.push({
178
- kind: 'ph-init',
179
- targetDir: path.dirname(result.appDir),
180
- appDir: result.appDir,
181
- spec,
182
- });
183
- }
184
- if (ei <= actionIndex('app-install')) {
185
- actions.push({ kind: 'app-install', dir: result.appDir });
186
- }
187
- if (ei <= actionIndex('app-ph-install') && extPkgs.length > 0) {
188
- const missing = await getMissingPhPackages(result.appDir, extPkgs);
189
- if (missing.length > 0) {
190
- actions.push({ kind: 'app-ph-install', appDir: result.appDir, packages: missing });
191
- }
192
- }
193
- if (ei <= actionIndex('app-build')) {
194
- // Add install if not already in the list and node_modules is missing
195
- if (!actions.some(a => a.kind === 'app-install') &&
196
- !(await fileExists(path.join(result.appDir, 'node_modules')))) {
197
- actions.push({ kind: 'app-install', dir: result.appDir });
198
- }
199
- actions.push({ kind: 'app-build', dir: result.appDir });
200
- }
201
- if (ei <= actionIndex('cli-install')) {
202
- actions.push({ kind: 'cli-install', dir: result.cliDir });
203
- }
204
- if (ei <= actionIndex('cli-build')) {
205
- // Add install if not already in the list and node_modules is missing
206
- if (!actions.some(a => a.kind === 'cli-install') &&
207
- !(await fileExists(path.join(result.cliDir, 'node_modules')))) {
208
- actions.push({ kind: 'cli-install', dir: result.cliDir });
209
- }
210
- actions.push({ kind: 'cli-build', dir: result.cliDir });
211
- }
212
- }
213
- else if (earliest && !split) {
214
- const ei = actionIndex(earliest);
215
- if (ei <= actionIndex('cli-install')) {
216
- actions.push({ kind: 'cli-install', dir: result.cliDir });
217
- }
218
- if (ei <= actionIndex('cli-build')) {
219
- // Add install if not already in the list and node_modules is missing
220
- if (!actions.some(a => a.kind === 'cli-install') &&
221
- !(await fileExists(path.join(result.cliDir, 'node_modules')))) {
222
- actions.push({ kind: 'cli-install', dir: result.cliDir });
223
- }
224
- actions.push({ kind: 'cli-build', dir: result.cliDir });
225
- }
226
- }
227
- // skills-sync is independent — append if needed
228
- if (spec.externalSkills.length > 0) {
229
- const targetDir = split ? result.cliDir : result.cliDir;
230
- actions.push({
231
- kind: 'skills-sync',
232
- targetDir,
233
- desired: spec.externalSkills,
234
- });
235
- }
236
- return actions;
237
- }
238
- // ---------------------------------------------------------------------------
239
- // Human-readable label for an action
240
- // ---------------------------------------------------------------------------
241
- function actionLabel(action) {
242
- switch (action.kind) {
243
- case 'ph-init':
244
- return `Initialize reactor package (${path.basename(action.appDir)})`;
245
- case 'app-install':
246
- return `Install dependencies (${path.basename(action.dir)})`;
247
- case 'app-ph-install':
248
- return `Register external packages (${action.packages.join(', ')})`;
249
- case 'app-build':
250
- return `Build (${path.basename(action.dir)})`;
251
- case 'cli-install':
252
- return `Install dependencies (${path.basename(action.dir)})`;
253
- case 'cli-build':
254
- return `Build (${path.basename(action.dir)})`;
255
- case 'skills-sync':
256
- return `Sync external skills (${action.desired.length} skill${action.desired.length === 1 ? '' : 's'})`;
257
- }
258
- }
259
- // ---------------------------------------------------------------------------
260
- // runPostGenActions — effectful runner
261
- // ---------------------------------------------------------------------------
262
- export async function runPostGenActions(actions, ctx) {
263
- if (actions.length === 0)
264
- return [];
265
- const skip = ctx.skip ?? new Set();
266
- // Filter out explicitly skipped actions. Also skip builds if their
267
- // corresponding install is skipped (building without install is pointless).
268
- const effective = actions.filter((a) => {
269
- if (skip.has(a.kind))
270
- return false;
271
- // If app-install is skipped, also skip app-ph-install and app-build
272
- if (a.kind === 'app-ph-install' && skip.has('app-install'))
273
- return false;
274
- if (a.kind === 'app-build' && skip.has('app-install'))
275
- return false;
276
- // If cli-install is skipped, also skip cli-build
277
- if (a.kind === 'cli-build' && skip.has('cli-install'))
278
- return false;
279
- return true;
280
- });
281
- if (effective.length === 0)
282
- return [];
283
- // Print numbered summary
284
- ctx.log(`\nPost-generation steps (${effective.length}):`);
285
- effective.forEach((a, i) => {
286
- ctx.log(` ${i + 1}. ${actionLabel(a)}`);
287
- });
288
- ctx.log('');
289
- const results = [];
290
- const failed = new Set();
291
- for (let i = 0; i < effective.length; i++) {
292
- const action = effective[i];
293
- const label = actionLabel(action);
294
- const prefix = `[${i + 1}/${effective.length}]`;
295
- // Check if a dependency failed
296
- const failedDep = [...failed].find((f) => dependsOn(action.kind, f));
297
- if (failedDep) {
298
- ctx.log(`${prefix} ${label}... skipped (dependency failed)`);
299
- results.push({
300
- action,
301
- status: 'skipped',
302
- reason: 'dependency failed',
303
- durationMs: 0,
304
- });
305
- continue;
306
- }
307
- ctx.log(`${prefix} ${label}...`);
308
- const t0 = Date.now();
309
- try {
310
- const success = await executeAction(action, ctx);
311
- const elapsed = Date.now() - t0;
312
- if (success) {
313
- ctx.log(` done (${formatDuration(elapsed)})`);
314
- results.push({ action, status: 'success', durationMs: elapsed });
315
- }
316
- else {
317
- ctx.log(` FAILED`);
318
- results.push({ action, status: 'failed', durationMs: elapsed });
319
- failed.add(action.kind);
320
- }
321
- }
322
- catch (err) {
323
- const elapsed = Date.now() - t0;
324
- const msg = err instanceof Error ? err.message : String(err);
325
- ctx.log(` FAILED: ${msg}`);
326
- results.push({
327
- action,
328
- status: 'failed',
329
- reason: msg,
330
- durationMs: elapsed,
331
- });
332
- failed.add(action.kind);
333
- }
334
- }
335
- // Print summary
336
- const succeeded = results.filter((r) => r.status === 'success').length;
337
- const failedCount = results.filter((r) => r.status === 'failed').length;
338
- const skippedCount = results.filter((r) => r.status === 'skipped').length;
339
- ctx.log('');
340
- if (failedCount === 0 && skippedCount === 0) {
341
- ctx.log(`Post-generation: ${succeeded} step${succeeded === 1 ? '' : 's'} completed successfully.`);
342
- ctx.log('Ready — run `pnpm dev` to start.');
343
- }
344
- else {
345
- ctx.log(`Post-generation: ${succeeded} succeeded, ${failedCount} failed, ${skippedCount} skipped.`);
346
- if (failedCount > 0) {
347
- ctx.log('Fix the reported error(s) and re-run `ph-clint clint-project-regen`.');
348
- }
349
- }
350
- return results;
351
- }
352
- // ---------------------------------------------------------------------------
353
- // Action dispatch
354
- // ---------------------------------------------------------------------------
355
- async function executeAction(action, ctx) {
356
- switch (action.kind) {
357
- case 'ph-init': {
358
- const { runPhInit } = await import('./scaffold.js');
359
- const result = await runPhInit({
360
- targetDir: action.targetDir,
361
- appDir: action.appDir,
362
- spec: action.spec,
363
- log: (msg) => ctx.log(` ${msg}`),
364
- runProcess: ctx.runProcess,
365
- });
366
- if (!result.ran) {
367
- ctx.log(` ${result.reason ?? 'ph init did not run'}`);
368
- return false;
369
- }
370
- if (result.exitCode === 0) {
371
- // Mark app as initialized in generated state
372
- const { readGeneratedState, writeGeneratedState } = await import('./generated.js');
373
- const gen = await readGeneratedState(action.targetDir);
374
- if (gen) {
375
- gen.appInitialized = true;
376
- await writeGeneratedState(action.targetDir, gen);
377
- }
378
- }
379
- return result.exitCode === 0;
380
- }
381
- case 'app-ph-install': {
382
- const { runPhInstallPackages } = await import('./scaffold.js');
383
- return runPhInstallPackages({
384
- appDir: action.appDir,
385
- packages: action.packages,
386
- log: (msg) => ctx.log(` ${msg}`),
387
- runProcess: ctx.runProcess,
388
- });
389
- }
390
- case 'app-install':
391
- case 'cli-install': {
392
- const result = await ctx.runProcess('pnpm install', {
393
- cwd: action.dir,
394
- timeout: 300_000,
395
- });
396
- return result.success;
397
- }
398
- case 'app-build':
399
- case 'cli-build': {
400
- return runBuild(action.dir, ctx);
401
- }
402
- case 'skills-sync': {
403
- const { syncExternalSkills } = await import('../skills/sync.js');
404
- await syncExternalSkills({
405
- targetDir: action.targetDir,
406
- desired: action.desired,
407
- log: (msg) => ctx.log(` ${msg}`),
408
- });
409
- return true;
410
- }
411
- }
412
- }
413
- async function runBuild(dir, ctx) {
414
- const result = await ctx.runProcess('pnpm build', {
415
- cwd: dir,
416
- timeout: 120_000,
417
- });
418
- return result.success;
419
- }
420
- function formatDuration(ms) {
421
- if (ms < 1000)
422
- return `${ms}ms`;
423
- return `${(ms / 1000).toFixed(1)}s`;
424
- }
1
+ export { collectPostGenActions, runPostGenActions, } from '@powerhousedao/ph-clint-dev/codegen/actions';
@@ -11,29 +11,33 @@ import { getAppPackageName, getDocumentTypeSlug, isDocTypeGlob, phAtLeast, } fro
11
11
  export function buildAppIndexTs(spec) {
12
12
  if (!phAtLeast(spec.features.powerhouse, 'Reactor'))
13
13
  return null;
14
+ const lines = [];
15
+ // Standard Powerhouse reactor-package barrel — matches what `ph init`
16
+ // generates. Required by main.tsx (Connect) and cli.ts imports.
17
+ lines.push('// THIS FILE IS GENERATED BY ph-clint-cli.');
18
+ lines.push("import type { Manifest } from 'document-model';");
19
+ lines.push("import manifestJson from './powerhouse.manifest.json' with { type: 'json' };");
20
+ lines.push("export { documentModels } from './document-models/document-models.js';");
21
+ lines.push("export { upgradeManifests } from './document-models/upgrade-manifests.js';");
22
+ lines.push("export { editors } from './editors/editors.js';");
23
+ lines.push("export { processorFactory } from './processors/factory.js';");
24
+ lines.push('export const manifest: Manifest = manifestJson;');
25
+ // Per-document-type re-exports so impl code can import from
26
+ // '{name}-app' instead of drilling into deep paths.
14
27
  const appPkg = getAppPackageName(spec);
15
28
  const appEntry = spec.packages.find((p) => p.packageName === appPkg);
16
29
  const docTypes = appEntry?.documentTypes ?? [];
17
- if (docTypes.length === 0)
18
- return null;
19
- const hasGlobs = docTypes.some(isDocTypeGlob);
20
- const explicits = docTypes.filter((dt) => !isDocTypeGlob(dt));
21
- const lines = [];
22
- lines.push('// THIS FILE IS GENERATED BY ph-clint-cli.');
23
- lines.push('// Re-exports every registered document model from a single top-level');
24
- lines.push('// entry so impl code can `import { ... } from \'{name}-app\'`.');
25
- lines.push('');
26
- if (hasGlobs) {
27
- // Glob patterns can't enumerate slugs at codegen time — re-export
28
- // from the Powerhouse-generated barrel which already re-exports all
29
- // document models in the package.
30
- lines.push("export * from './document-models/index.js';");
31
- }
32
- // Explicit entries still get per-slug re-exports (they may point at
33
- // models not yet in the generated barrel during bootstrapping).
34
- for (const docType of explicits) {
35
- const slug = getDocumentTypeSlug(docType);
36
- lines.push(`export * from './document-models/${slug}/index.js';`);
30
+ if (docTypes.length > 0) {
31
+ const hasGlobs = docTypes.some(isDocTypeGlob);
32
+ const explicits = docTypes.filter((dt) => !isDocTypeGlob(dt));
33
+ lines.push('');
34
+ if (hasGlobs) {
35
+ lines.push("export * from './document-models/index.js';");
36
+ }
37
+ for (const docType of explicits) {
38
+ const slug = getDocumentTypeSlug(docType);
39
+ lines.push(`export * from './document-models/${slug}/index.js';`);
40
+ }
37
41
  }
38
42
  return lines.join('\n') + '\n';
39
43
  }
@@ -1,8 +1 @@
1
- /**
2
- * Builds the CLI-side `package.json` (the ph-clint CLI itself).
3
- *
4
- * When `features.powerhouse.enabled`, this file lives at
5
- * `{root}/{name}-cli/package.json`. Otherwise at `{root}/package.json`.
6
- */
7
- import { type ClintProjectSpec } from '../../spec/types.js';
8
- export declare function buildCliPackageJson(spec: ClintProjectSpec): string;
1
+ export { buildCliPackageJson } from '@powerhousedao/ph-clint-dev/codegen/builders';