@powerhousedao/ph-clint-cli 0.1.0-dev.10 → 0.1.0-dev.101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +53 -16
- package/dist/codegen/index.d.ts +8 -36
- package/dist/codegen/index.js +6 -293
- package/dist/commands/clint-project-build.d.ts +77 -1
- package/dist/commands/clint-project-build.js +11 -28
- package/dist/commands/clint-project-init.d.ts +130 -10
- package/dist/commands/clint-project-init.js +72 -47
- package/dist/commands/clint-project-publish.d.ts +78 -1
- package/dist/commands/clint-project-publish.js +6 -4
- package/dist/commands/clint-project-regen.d.ts +77 -1
- package/dist/commands/clint-project-regen.js +26 -2
- package/dist/commands/clint-skills-sync.d.ts +86 -0
- package/dist/commands/clint-skills-sync.js +56 -0
- package/dist/framework.d.ts +322 -60
- package/dist/framework.gen.d.ts +50 -10
- package/dist/framework.js +1 -5
- package/{prompts/agent-profiles/AgentBase.md → dist/gen/agent-profiles/PhClintDevAgent.md} +1 -1
- package/dist/gen/skills/cli-setup/.cli-docs.md +135 -0
- package/dist/gen/skills/cli-setup/SKILL.md +125 -0
- package/dist/gen/skills/cli-setup/references/00.assess-cli-needs.md +53 -0
- package/dist/gen/skills/cli-setup/references/01.define-config-schema.md +78 -0
- package/dist/gen/skills/cli-setup/references/02.wire-cli.md +141 -0
- package/dist/gen/skills/cli-setup/references/03.add-entrypoint.md +128 -0
- package/dist/gen/skills/cli-setup/references/expected-outcome.md +3 -0
- package/dist/gen/skills/command-definition/.cli-docs.md +84 -0
- package/dist/gen/skills/command-definition/SKILL.md +99 -0
- package/dist/gen/skills/command-definition/references/00.assess-requirements.md +58 -0
- package/dist/gen/skills/command-definition/references/01.define-schema.md +72 -0
- package/dist/gen/skills/command-definition/references/02.implement-execute.md +118 -0
- package/dist/gen/skills/command-definition/references/03.add-prompting.md +54 -0
- package/dist/gen/skills/command-definition/references/expected-outcome.md +3 -0
- package/dist/gen/skills/service-definition/.cli-docs.md +214 -0
- package/dist/gen/skills/service-definition/SKILL.md +148 -0
- package/dist/gen/skills/service-definition/references/00.assess-service.md +69 -0
- package/dist/gen/skills/service-definition/references/01.define-service.md +166 -0
- package/dist/gen/skills/service-definition/references/02.add-preflight.md +132 -0
- package/dist/gen/skills/service-definition/references/03.add-project-scanner.md +82 -0
- package/dist/gen/skills/service-definition/references/04.wire-events.md +120 -0
- package/dist/gen/skills/service-definition/references/expected-outcome.md +3 -0
- package/dist/main.js +0 -0
- package/dist/services/clint-project.js +21 -0
- package/dist/spec/ensure-document.d.ts +17 -0
- package/dist/spec/ensure-document.js +56 -0
- package/dist/spec/file.d.ts +1 -4
- package/dist/spec/file.js +1 -34
- package/dist/spec/from-document.d.ts +4 -1
- package/dist/spec/from-document.js +4 -16
- package/dist/spec/types.d.ts +1 -62
- package/dist/spec/types.js +1 -112
- package/dist/triggers/publish-trigger.d.ts +81 -0
- package/dist/triggers/publish-trigger.js +137 -0
- package/dist/triggers/spec-change.d.ts +60 -18
- package/dist/triggers/spec-change.js +154 -101
- package/package.json +26 -31
- package/dist/codegen/builders/agent-base-md.d.ts +0 -5
- package/dist/codegen/builders/agent-base-md.js +0 -18
- package/dist/codegen/builders/agent-ts.d.ts +0 -9
- package/dist/codegen/builders/agent-ts.js +0 -34
- package/dist/codegen/builders/app-index-ts.d.ts +0 -18
- package/dist/codegen/builders/app-index-ts.js +0 -33
- package/dist/codegen/builders/build-skills-ts.d.ts +0 -4
- package/dist/codegen/builders/build-skills-ts.js +0 -37
- package/dist/codegen/builders/cli-package-json.d.ts +0 -8
- package/dist/codegen/builders/cli-package-json.js +0 -96
- package/dist/codegen/builders/cli-ts.d.ts +0 -7
- package/dist/codegen/builders/cli-ts.js +0 -132
- package/dist/codegen/builders/config-ts.d.ts +0 -8
- package/dist/codegen/builders/config-ts.js +0 -17
- package/dist/codegen/builders/eslint-config-js.d.ts +0 -4
- package/dist/codegen/builders/eslint-config-js.js +0 -13
- package/dist/codegen/builders/framework-gen-ts.d.ts +0 -20
- package/dist/codegen/builders/framework-gen-ts.js +0 -62
- package/dist/codegen/builders/framework-ts.d.ts +0 -21
- package/dist/codegen/builders/framework-ts.js +0 -74
- package/dist/codegen/builders/gitignore.d.ts +0 -4
- package/dist/codegen/builders/gitignore.js +0 -18
- package/dist/codegen/builders/index.d.ts +0 -44
- package/dist/codegen/builders/index.js +0 -61
- package/dist/codegen/builders/jest-config-js.d.ts +0 -4
- package/dist/codegen/builders/jest-config-js.js +0 -19
- package/dist/codegen/builders/main-ts.d.ts +0 -5
- package/dist/codegen/builders/main-ts.js +0 -13
- package/dist/codegen/builders/mastra-index-ts.d.ts +0 -8
- package/dist/codegen/builders/mastra-index-ts.js +0 -30
- package/dist/codegen/builders/publish-config-ts.d.ts +0 -6
- package/dist/codegen/builders/publish-config-ts.js +0 -18
- package/dist/codegen/builders/readme-md.d.ts +0 -5
- package/dist/codegen/builders/readme-md.js +0 -44
- package/dist/codegen/builders/root-package-json.d.ts +0 -10
- package/dist/codegen/builders/root-package-json.js +0 -40
- package/dist/codegen/builders/tsconfig-json.d.ts +0 -4
- package/dist/codegen/builders/tsconfig-json.js +0 -22
- package/dist/codegen/exec.d.ts +0 -20
- package/dist/codegen/exec.js +0 -41
- package/dist/codegen/hashes.d.ts +0 -6
- package/dist/codegen/hashes.js +0 -60
- package/dist/codegen/markers.d.ts +0 -36
- package/dist/codegen/markers.js +0 -86
- package/dist/codegen/migrate/flat-to-split.d.ts +0 -15
- package/dist/codegen/migrate/flat-to-split.js +0 -119
- package/dist/codegen/scaffold.d.ts +0 -34
- package/dist/codegen/scaffold.js +0 -60
- package/dist/codegen/write.d.ts +0 -6
- package/dist/codegen/write.js +0 -32
- package/dist/commands/init.d.ts +0 -57
- package/dist/commands/init.js +0 -168
- package/dist/commands/regen.d.ts +0 -18
- package/dist/commands/regen.js +0 -68
- package/prompts/skills-ext/.gitkeep +0 -0
- package/prompts/skills-tpl/.gitkeep +0 -0
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `spec-change` trigger — watches
|
|
3
|
-
*
|
|
4
|
-
* that re-runs the code generator in update mode.
|
|
2
|
+
* `spec-change` trigger — watches ALL `powerhouse/ph-clint-project` documents
|
|
3
|
+
* and, when any change, re-runs the code generator for each affected project.
|
|
5
4
|
*
|
|
6
5
|
* Flow:
|
|
7
6
|
* 1. `createDocumentChangeTrigger` (from ph-clint) owns the subscription,
|
|
8
|
-
* event coalescing, doc loading, and type narrowing.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* 3.
|
|
7
|
+
* event coalescing, doc loading, and type narrowing. No `documentId` is
|
|
8
|
+
* set, so it loads ALL matching documents on each poll.
|
|
9
|
+
* 2. `getProjectMapping()` merges an on-disk scan (via the clint-project
|
|
10
|
+
* service's projectScanner) with personal-drive folder entries to
|
|
11
|
+
* correlate each document to an on-disk project directory.
|
|
12
|
+
* 3. For each document, `specFromDocumentState()` builds a spec, hashes it,
|
|
14
13
|
* and compares against `.ph/ph-clint-cli/.last-spec-hash`. If unchanged,
|
|
15
|
-
*
|
|
16
|
-
* `generateProject(spec, workdir, 'update')` and writes the new hash.
|
|
14
|
+
* skips. Otherwise regenerates at the mapped target directory.
|
|
17
15
|
*/
|
|
18
16
|
import crypto from 'node:crypto';
|
|
19
17
|
import fs from 'node:fs/promises';
|
|
20
18
|
import path from 'node:path';
|
|
19
|
+
import { scanProjects, getProjectMapping } from '@powerhousedao/ph-clint';
|
|
21
20
|
import { createDocumentChangeTrigger } from '../framework.js';
|
|
22
21
|
import { generateProject } from '../codegen/index.js';
|
|
22
|
+
import { runPostGenActions } from '@powerhousedao/ph-clint-dev/codegen/actions';
|
|
23
23
|
import { specFromDocumentState } from '../spec/from-document.js';
|
|
24
|
+
import { readProjectSpec, writeProjectSpec } from '../spec/file.js';
|
|
25
|
+
import { ensureSpecDocument } from '../spec/ensure-document.js';
|
|
26
|
+
import { clintProject } from '../services/clint-project.js';
|
|
24
27
|
const DOCUMENT_TYPE = 'powerhouse/ph-clint-project';
|
|
25
28
|
const HASH_DIR = path.join('.ph', 'ph-clint-cli');
|
|
26
29
|
const HASH_FILE = '.last-spec-hash';
|
|
@@ -49,11 +52,13 @@ async function writeLastSpecHash(targetDir, hash) {
|
|
|
49
52
|
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
50
53
|
await fs.writeFile(file, hash + '\n', 'utf8');
|
|
51
54
|
}
|
|
52
|
-
/** Stable hash of a ClintProjectSpec (sha256 of canonical-key JSON).
|
|
55
|
+
/** Stable hash of a ClintProjectSpec (sha256 of canonical-key JSON).
|
|
56
|
+
* Excludes documentId/documentType — they don't affect codegen output. */
|
|
53
57
|
export function hashSpec(spec) {
|
|
58
|
+
const { documentId, documentType, ...codegenRelevant } = spec;
|
|
54
59
|
return crypto
|
|
55
60
|
.createHash('sha256')
|
|
56
|
-
.update(canonicalJson(
|
|
61
|
+
.update(canonicalJson(codegenRelevant), 'utf8')
|
|
57
62
|
.digest('hex');
|
|
58
63
|
}
|
|
59
64
|
function canonicalJson(value) {
|
|
@@ -70,102 +75,150 @@ function canonicalJson(value) {
|
|
|
70
75
|
.join(',') +
|
|
71
76
|
'}');
|
|
72
77
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
export function specToImportInput(spec) {
|
|
79
|
+
const main = spec.features.mastra.mainAgent;
|
|
80
|
+
return {
|
|
81
|
+
name: spec.name,
|
|
82
|
+
scope: spec.scope ?? null,
|
|
83
|
+
version: spec.version,
|
|
84
|
+
description: spec.description,
|
|
85
|
+
powerhouse: spec.features.powerhouse,
|
|
86
|
+
mastraEnabled: spec.features.mastra.enabled,
|
|
87
|
+
routineEnabled: spec.features.routine.enabled,
|
|
88
|
+
mainAgent: main
|
|
89
|
+
? {
|
|
90
|
+
id: main.id,
|
|
91
|
+
name: main.name,
|
|
92
|
+
description: main.description,
|
|
93
|
+
attachment: main.image,
|
|
94
|
+
modelId: main.modelId,
|
|
95
|
+
profileIds: [...main.profileIds],
|
|
96
|
+
skills: [...main.skills],
|
|
97
|
+
toolPatterns: [...main.toolPatterns],
|
|
81
98
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
99
|
+
: null,
|
|
100
|
+
subAgents: spec.features.mastra.subAgents.map((s) => ({
|
|
101
|
+
id: s.id,
|
|
102
|
+
name: s.name,
|
|
103
|
+
description: s.description,
|
|
104
|
+
modelId: s.modelId,
|
|
105
|
+
profileIds: [...s.profileIds],
|
|
106
|
+
skills: [...s.skills],
|
|
107
|
+
toolPatterns: [...s.toolPatterns],
|
|
108
|
+
})),
|
|
109
|
+
models: spec.features.mastra.models.map((m) => ({
|
|
110
|
+
id: m.id,
|
|
111
|
+
})),
|
|
112
|
+
profiles: spec.features.mastra.profiles.map((p) => ({
|
|
113
|
+
id: p.id,
|
|
114
|
+
title: p.title,
|
|
115
|
+
content: p.content,
|
|
116
|
+
})),
|
|
117
|
+
packages: spec.packages.map((p) => ({
|
|
118
|
+
id: p.id,
|
|
119
|
+
packageName: p.packageName,
|
|
120
|
+
documentTypes: p.documentTypes,
|
|
121
|
+
})),
|
|
122
|
+
externalSkills: spec.externalSkills.map((s) => ({
|
|
123
|
+
id: s.id,
|
|
124
|
+
name: s.name,
|
|
125
|
+
githubUrl: s.githubUrl,
|
|
126
|
+
})),
|
|
127
|
+
enableChat: spec.features.mastra.common.enableChat,
|
|
128
|
+
proxyEnabled: spec.deployment.proxyEnabled,
|
|
129
|
+
observabilityEnabled: spec.deployment.observabilityEnabled,
|
|
130
|
+
supportedResources: spec.deployment.supportedResources,
|
|
131
|
+
};
|
|
88
132
|
}
|
|
89
133
|
export const specChangeTrigger = createDocumentChangeTrigger({
|
|
90
134
|
id: 'spec-change',
|
|
91
135
|
documentType: DOCUMENT_TYPE,
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
136
|
+
// No documentId → watches ALL ph-clint-project docs
|
|
137
|
+
callOnEmpty: true, // bootstrap from disk when no documents exist yet
|
|
138
|
+
async onChange(docs, ctx) {
|
|
139
|
+
const log = ctx.context.log;
|
|
140
|
+
const folders = ctx.context.folders;
|
|
141
|
+
// Build the mapping: on-disk projects + personal drive documents
|
|
142
|
+
const scanner = clintProject.projectScanner;
|
|
143
|
+
const scanResults = scanner
|
|
144
|
+
? scanProjects(ctx.context.workdir, scanner)
|
|
145
|
+
: [];
|
|
146
|
+
const mapping = await getProjectMapping(scanResults, folders);
|
|
147
|
+
// Auto-create spec documents for unlinked or orphaned projects
|
|
101
148
|
const reactor = await ctx.reactor();
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
149
|
+
if (reactor && folders) {
|
|
150
|
+
for (const entry of mapping) {
|
|
151
|
+
if (!entry.path)
|
|
152
|
+
continue;
|
|
153
|
+
const existingSpec = await readProjectSpec(entry.path);
|
|
154
|
+
if (!existingSpec)
|
|
155
|
+
continue;
|
|
156
|
+
try {
|
|
157
|
+
const { docId, created } = await ensureSpecDocument({
|
|
158
|
+
spec: existingSpec,
|
|
159
|
+
targetDir: entry.path,
|
|
160
|
+
reactor,
|
|
161
|
+
folders,
|
|
162
|
+
});
|
|
163
|
+
if (created) {
|
|
164
|
+
log?.info(`${TAG} linked project ${entry.name} to document ${docId}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
log?.warn(`${TAG} could not ensure spec document for ${entry.name}: ${err instanceof Error ? err.message : String(err)}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
108
171
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
172
|
+
for (const doc of docs) {
|
|
173
|
+
const spec = specFromDocumentState(doc.state.global, {
|
|
174
|
+
documentId: doc.header.id,
|
|
175
|
+
documentType: doc.header.documentType,
|
|
176
|
+
});
|
|
177
|
+
if (!spec) {
|
|
178
|
+
log?.debug(`${TAG} document ${doc.header.id} state did not validate against ClintProjectSpec, skipping`);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
// Find target directory from mapping
|
|
182
|
+
const entry = mapping.find((m) => m.documentId === doc.header.id);
|
|
183
|
+
const targetDir = entry?.path ?? path.join(ctx.context.workdir, spec.name);
|
|
184
|
+
// Per-project hash comparison
|
|
185
|
+
const nextHash = hashSpec(spec);
|
|
186
|
+
const prevHash = await readLastSpecHash(targetDir);
|
|
187
|
+
if (nextHash === prevHash) {
|
|
188
|
+
log?.debug(`${TAG} spec for ${spec.name} unchanged (hash=${nextHash.slice(0, 12)}…), skipping`);
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
log?.debug(`${TAG} spec for ${spec.name} changed: ${prevHash ? prevHash.slice(0, 12) + '…' : '<none>'} → ${nextHash.slice(0, 12)}…`);
|
|
192
|
+
log?.info(`${TAG} regenerating ${spec.name} at ${targetDir} (doc=${doc.header.id})`);
|
|
193
|
+
const t0 = Date.now();
|
|
194
|
+
const warnings = [];
|
|
195
|
+
const result = await generateProject({
|
|
196
|
+
targetDir,
|
|
197
|
+
spec,
|
|
198
|
+
mode: 'update',
|
|
199
|
+
force: true,
|
|
200
|
+
onWarn: (m) => warnings.push(m),
|
|
201
|
+
});
|
|
202
|
+
// Write spec JSON with documentId
|
|
203
|
+
await writeProjectSpec(targetDir, spec);
|
|
204
|
+
await writeLastSpecHash(targetDir, nextHash);
|
|
205
|
+
const elapsed = Date.now() - t0;
|
|
206
|
+
if (log) {
|
|
207
|
+
if (result.migrated)
|
|
208
|
+
log.info(`${TAG} migrated flat → split layout`);
|
|
209
|
+
log.info(`${TAG} regenerated ${spec.name} in ${elapsed}ms: ${result.files.length} written, ${result.skipped.length} skipped, ${result.deleted.length} deleted`);
|
|
210
|
+
for (const w of warnings)
|
|
211
|
+
log.warn(`${TAG} ${w}`);
|
|
212
|
+
}
|
|
213
|
+
// Run post-generation actions (ph-init, install, build, skills-sync).
|
|
214
|
+
// Route through ctx.context.stdout so output flows through
|
|
215
|
+
// routine.onOutput → service log buffer → ServicePanel.
|
|
216
|
+
await runPostGenActions(result.pendingActions, {
|
|
217
|
+
log: (msg) => ctx.context.stdout(`${TAG} ${msg}\n`),
|
|
218
|
+
runProcess: ctx.context.runProcess,
|
|
115
219
|
});
|
|
116
|
-
ctx.context.config.projectDocumentId = discovered;
|
|
117
|
-
ctx.context.log?.info(`${TAG} pinned projectDocumentId=${discovered} in ${ctx.context.workspace.getLocalConfigPath()}`);
|
|
118
|
-
}
|
|
119
|
-
catch (err) {
|
|
120
|
-
ctx.context.log?.warn(`${TAG} failed to persist projectDocumentId: ${err instanceof Error ? err.message : String(err)}`);
|
|
121
|
-
}
|
|
122
|
-
return discovered;
|
|
123
|
-
},
|
|
124
|
-
async onChange(doc, ctx) {
|
|
125
|
-
const log = ctx.context.log;
|
|
126
|
-
const spec = specFromDocumentState(doc.state.global);
|
|
127
|
-
if (!spec) {
|
|
128
|
-
log?.debug(`${TAG} document ${doc.header.id} state did not validate against ClintProjectSpec, skipping`);
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
const targetDir = ctx.context.workdir;
|
|
132
|
-
const nextHash = hashSpec(spec);
|
|
133
|
-
const prevHash = await readLastSpecHash(targetDir);
|
|
134
|
-
if (nextHash === prevHash) {
|
|
135
|
-
log?.debug(`${TAG} spec unchanged (hash=${nextHash.slice(0, 12)}…), nothing to do`);
|
|
136
|
-
return null;
|
|
137
220
|
}
|
|
138
|
-
|
|
139
|
-
return
|
|
140
|
-
type: 'function',
|
|
141
|
-
params: {
|
|
142
|
-
fn: async () => {
|
|
143
|
-
log?.info(`${TAG} regenerating project at ${targetDir} (doc=${doc.header.id})`);
|
|
144
|
-
const t0 = Date.now();
|
|
145
|
-
const warnings = [];
|
|
146
|
-
const result = await generateProject({
|
|
147
|
-
targetDir,
|
|
148
|
-
spec,
|
|
149
|
-
mode: 'update',
|
|
150
|
-
onWarn: (m) => warnings.push(m),
|
|
151
|
-
});
|
|
152
|
-
await writeLastSpecHash(targetDir, nextHash);
|
|
153
|
-
const elapsed = Date.now() - t0;
|
|
154
|
-
if (log) {
|
|
155
|
-
if (result.migrated)
|
|
156
|
-
log.info(`${TAG} migrated flat → split layout`);
|
|
157
|
-
log.info(`${TAG} regenerated in ${elapsed}ms: ${result.files.length} written, ${result.skipped.length} skipped, ${result.deleted.length} deleted`);
|
|
158
|
-
for (const w of warnings)
|
|
159
|
-
log.warn(`${TAG} ${w}`);
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
callbacks: {
|
|
164
|
-
onFailure: (err) => {
|
|
165
|
-
log?.error(`${TAG} regen failed: ${err.message}`);
|
|
166
|
-
log?.debug(`${TAG} stack: ${err.stack ?? '<no stack>'}`);
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
};
|
|
221
|
+
// Work done inline, no additional work item needed
|
|
222
|
+
return null;
|
|
170
223
|
},
|
|
171
224
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/ph-clint-cli",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.101",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -10,40 +10,23 @@
|
|
|
10
10
|
"ph-clint": "./dist/main.js"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
-
"dist"
|
|
14
|
-
"prompts"
|
|
13
|
+
"dist"
|
|
15
14
|
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"build:skills": "tsx scripts/build-skills.ts",
|
|
18
|
-
"build": "pnpm build:skills && tsc",
|
|
19
|
-
"dev": "tsx src/main.ts",
|
|
20
|
-
"start": "node dist/main.js",
|
|
21
|
-
"test": "NODE_OPTIONS='--experimental-vm-modules' jest --detectOpenHandles",
|
|
22
|
-
"lint": "eslint src",
|
|
23
|
-
"mastra:dev": "mastra dev",
|
|
24
|
-
"mastra:build": "mastra build",
|
|
25
|
-
"mastra:start": "mastra start"
|
|
26
|
-
},
|
|
27
15
|
"dependencies": {
|
|
28
|
-
"@powerhousedao/ph-clint": "^0.1.0-dev.10",
|
|
29
|
-
"@powerhousedao/ph-clint-app": "^0.1.0-dev.10",
|
|
30
|
-
"@mastra/core": "^1.22.0",
|
|
31
|
-
"@mastra/libsql": "^1.7.4",
|
|
32
|
-
"@mastra/memory": "^1.13.1",
|
|
33
|
-
"@powerhousedao/reactor": "6.0.0-dev.170",
|
|
34
|
-
"@powerhousedao/reactor-api": "6.0.0-dev.170",
|
|
35
|
-
"@powerhousedao/shared": "6.0.0-dev.170",
|
|
36
16
|
"@electric-sql/pglite": "0.3.15",
|
|
37
|
-
"
|
|
17
|
+
"@mastra/core": "^1.41.0",
|
|
18
|
+
"@mastra/libsql": "^1.12.1",
|
|
19
|
+
"@mastra/memory": "^1.20.2",
|
|
20
|
+
"@powerhousedao/reactor": "6.2.0-rc.6",
|
|
21
|
+
"@powerhousedao/reactor-api": "6.2.0-rc.6",
|
|
22
|
+
"@powerhousedao/shared": "6.2.0-rc.6",
|
|
23
|
+
"document-model": "6.2.0-rc.6",
|
|
38
24
|
"kysely": "^0.27.0",
|
|
39
25
|
"kysely-pglite-dialect": "^1.3.0",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"overrides": {
|
|
45
|
-
"mastra>@mastra/deployer": "1.22.0"
|
|
46
|
-
}
|
|
26
|
+
"zod": "4.3.6",
|
|
27
|
+
"@powerhousedao/ph-clint-app": "0.1.0-dev.101",
|
|
28
|
+
"@powerhousedao/ph-clint-dev": "0.1.0-dev.101",
|
|
29
|
+
"@powerhousedao/ph-clint": "0.1.0-dev.101"
|
|
47
30
|
},
|
|
48
31
|
"devDependencies": {
|
|
49
32
|
"@jest/globals": "^30.2.0",
|
|
@@ -55,5 +38,17 @@
|
|
|
55
38
|
},
|
|
56
39
|
"engines": {
|
|
57
40
|
"node": ">=22.13.0"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build:skills": "tsx scripts/build-skills.ts",
|
|
44
|
+
"build": "pnpm build:skills && tsc",
|
|
45
|
+
"dev": "tsx src/main.ts",
|
|
46
|
+
"start": "node dist/main.js",
|
|
47
|
+
"test": "NODE_OPTIONS='--experimental-vm-modules' jest --detectOpenHandles --coverage",
|
|
48
|
+
"test:e2e": "NODE_OPTIONS='--experimental-vm-modules' jest --detectOpenHandles --testPathPatterns 'tests/(e2e|codegen-e2e)/' --testPathIgnorePatterns '/node_modules/'",
|
|
49
|
+
"lint": "eslint src",
|
|
50
|
+
"mastra:dev": "mastra dev",
|
|
51
|
+
"mastra:build": "mastra build",
|
|
52
|
+
"mastra:start": "mastra start"
|
|
58
53
|
}
|
|
59
|
-
}
|
|
54
|
+
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Builds `prompts/agent-profiles/AgentBase.md` — the minimal base profile.
|
|
3
|
-
*/
|
|
4
|
-
import { getPackageName, } from '../../spec/types.js';
|
|
5
|
-
export function buildAgentBaseMd(spec) {
|
|
6
|
-
return [
|
|
7
|
-
'# Agent Base System Prompt',
|
|
8
|
-
'',
|
|
9
|
-
`You are {{agentName}}, an agent available through the ${getPackageName(spec)} CLI.`,
|
|
10
|
-
'',
|
|
11
|
-
'## Capabilities',
|
|
12
|
-
'',
|
|
13
|
-
'This base profile is a minimal placeholder. Extend it with project-specific',
|
|
14
|
-
"context, workflows, and domain knowledge. Additional sections listed in the",
|
|
15
|
-
"agent's `sections` array are concatenated after this file at build time.",
|
|
16
|
-
'',
|
|
17
|
-
].join('\n');
|
|
18
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Builds `src/agents/agent.ts` — a minimal Mastra agent factory.
|
|
3
|
-
*
|
|
4
|
-
* Emitted only when `features.mastra.enabled`. The generated agent falls back
|
|
5
|
-
* to a deterministic echo-style demo provider when no API key is configured,
|
|
6
|
-
* so `pnpm dev` works immediately out of the box.
|
|
7
|
-
*/
|
|
8
|
-
import { type ClintProjectSpec } from '../../spec/types.js';
|
|
9
|
-
export declare function buildAgentTs(spec: ClintProjectSpec): string;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
export function buildAgentTs(spec) {
|
|
2
|
-
const id = spec.name;
|
|
3
|
-
return [
|
|
4
|
-
"import type { AgentProvider, AgentSetupContext, StreamChunk } from '@powerhousedao/ph-clint';",
|
|
5
|
-
"import type { Config } from '../framework.js';",
|
|
6
|
-
'',
|
|
7
|
-
'/**',
|
|
8
|
-
' * Demo agent — deterministic echo responses. Replace with a real Mastra',
|
|
9
|
-
" * `Agent` once you've wired your model + tools.",
|
|
10
|
-
' */',
|
|
11
|
-
'function createDemoAgent(): AgentProvider {',
|
|
12
|
-
' return {',
|
|
13
|
-
` id: '${id}',`,
|
|
14
|
-
' async *stream(prompt) {',
|
|
15
|
-
' yield {',
|
|
16
|
-
" type: 'text-delta',",
|
|
17
|
-
" text: `You said: ${prompt}\\n(demo mode — set an API key and replace createDemoAgent with a Mastra Agent)`,",
|
|
18
|
-
' } satisfies StreamChunk;',
|
|
19
|
-
' },',
|
|
20
|
-
' };',
|
|
21
|
-
'}',
|
|
22
|
-
'',
|
|
23
|
-
'/**',
|
|
24
|
-
' * Agent factory invoked by `cli.configureAgent`. Receives the resolved',
|
|
25
|
-
' * config and workdir; return an AgentProvider.',
|
|
26
|
-
' */',
|
|
27
|
-
'export async function createAgent(',
|
|
28
|
-
' _ctx: AgentSetupContext<Config>,',
|
|
29
|
-
'): Promise<AgentProvider> {',
|
|
30
|
-
' return createDemoAgent();',
|
|
31
|
-
'}',
|
|
32
|
-
'',
|
|
33
|
-
].join('\n');
|
|
34
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Builds `{name}-app/index.ts` — the top-level re-export barrel for the
|
|
3
|
-
* reactor package. Impl code imports from `'{name}-app'` instead of drilling
|
|
4
|
-
* into `'{name}-app/document-models/<slug>/v1/gen/...'`.
|
|
5
|
-
*
|
|
6
|
-
* Each entry re-exports a document-model subfolder's `index.ts`, which in
|
|
7
|
-
* turn re-exports the module object (`PhClintProject`, ...), action creators,
|
|
8
|
-
* document/state types, and type guards. Fully machine-owned: regen on every
|
|
9
|
-
* run.
|
|
10
|
-
*
|
|
11
|
-
* Powerhouse's own codegen might emit its own `index.ts` (as is the case for
|
|
12
|
-
* ph-clint-app today, which has manifest/editors/processors re-exports). When
|
|
13
|
-
* that exists, leave it alone — users hand-merge. Our codegen only emits when
|
|
14
|
-
* the file is absent or was emitted by a previous ph-clint-cli run (hash
|
|
15
|
-
* matches the ledger).
|
|
16
|
-
*/
|
|
17
|
-
import { type ClintProjectSpec } from '../../spec/types.js';
|
|
18
|
-
export declare function buildAppIndexTs(spec: ClintProjectSpec): string | null;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Builds `{name}-app/index.ts` — the top-level re-export barrel for the
|
|
3
|
-
* reactor package. Impl code imports from `'{name}-app'` instead of drilling
|
|
4
|
-
* into `'{name}-app/document-models/<slug>/v1/gen/...'`.
|
|
5
|
-
*
|
|
6
|
-
* Each entry re-exports a document-model subfolder's `index.ts`, which in
|
|
7
|
-
* turn re-exports the module object (`PhClintProject`, ...), action creators,
|
|
8
|
-
* document/state types, and type guards. Fully machine-owned: regen on every
|
|
9
|
-
* run.
|
|
10
|
-
*
|
|
11
|
-
* Powerhouse's own codegen might emit its own `index.ts` (as is the case for
|
|
12
|
-
* ph-clint-app today, which has manifest/editors/processors re-exports). When
|
|
13
|
-
* that exists, leave it alone — users hand-merge. Our codegen only emits when
|
|
14
|
-
* the file is absent or was emitted by a previous ph-clint-cli run (hash
|
|
15
|
-
* matches the ledger).
|
|
16
|
-
*/
|
|
17
|
-
import { getDocumentTypeSlug, } from '../../spec/types.js';
|
|
18
|
-
export function buildAppIndexTs(spec) {
|
|
19
|
-
if (!spec.features.powerhouse.enabled)
|
|
20
|
-
return null;
|
|
21
|
-
if (spec.documentTypes.length === 0)
|
|
22
|
-
return null;
|
|
23
|
-
const lines = [];
|
|
24
|
-
lines.push('// THIS FILE IS GENERATED BY ph-clint-cli.');
|
|
25
|
-
lines.push('// Re-exports every registered document model from a single top-level');
|
|
26
|
-
lines.push('// entry so impl code can `import { ... } from \'{name}-app\'`.');
|
|
27
|
-
lines.push('');
|
|
28
|
-
for (const docType of spec.documentTypes) {
|
|
29
|
-
const slug = getDocumentTypeSlug(docType);
|
|
30
|
-
lines.push(`export * from './document-models/${slug}/index.js';`);
|
|
31
|
-
}
|
|
32
|
-
return lines.join('\n') + '\n';
|
|
33
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Builds `scripts/build-skills.ts` — the build-time skill compiler.
|
|
3
|
-
*/
|
|
4
|
-
export function buildBuildSkillsScript() {
|
|
5
|
-
return [
|
|
6
|
-
'#!/usr/bin/env tsx',
|
|
7
|
-
'/**',
|
|
8
|
-
' * Build script — compiles Handlebars templates in `prompts/` into static',
|
|
9
|
-
' * SKILL.md files and agent instruction strings under `gen/`, using',
|
|
10
|
-
" * ph-clint-dev's `buildSkills`.",
|
|
11
|
-
' */',
|
|
12
|
-
"import path from 'node:path';",
|
|
13
|
-
"import { buildSkills } from '@powerhousedao/ph-clint-dev';",
|
|
14
|
-
"import { cli } from '../src/cli.js';",
|
|
15
|
-
'',
|
|
16
|
-
'const PROJECT_ROOT = path.resolve(import.meta.dirname, \'..\');',
|
|
17
|
-
'',
|
|
18
|
-
'// @clint:begin templateVars',
|
|
19
|
-
'function loadTemplateVars(): Record<string, string> {',
|
|
20
|
-
' return {',
|
|
21
|
-
" agentName: '{{AGENT_NAME}}',",
|
|
22
|
-
' };',
|
|
23
|
-
'}',
|
|
24
|
-
'// @clint:end templateVars',
|
|
25
|
-
'',
|
|
26
|
-
'buildSkills({',
|
|
27
|
-
" include: [path.join(PROJECT_ROOT, 'prompts')],",
|
|
28
|
-
' context: loadTemplateVars(),',
|
|
29
|
-
' output: [',
|
|
30
|
-
" path.join(PROJECT_ROOT, 'gen'),",
|
|
31
|
-
" path.join(PROJECT_ROOT, 'dist', 'gen'),",
|
|
32
|
-
' ],',
|
|
33
|
-
' cli,',
|
|
34
|
-
'});',
|
|
35
|
-
'',
|
|
36
|
-
].join('\n');
|
|
37
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
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,96 +0,0 @@
|
|
|
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 { getBinName, getPackageName, } from '../../spec/types.js';
|
|
8
|
-
import { CLI_VERSION } from '../../config.js';
|
|
9
|
-
/**
|
|
10
|
-
* Derive a semver range from the running ph-clint-cli version that respects
|
|
11
|
-
* the dev / staging / production channel boundary. This is the version range
|
|
12
|
-
* emitted into *scaffolded* projects' package.json for @powerhousedao/ph-clint
|
|
13
|
-
* and @powerhousedao/ph-clint-dev dependencies.
|
|
14
|
-
*
|
|
15
|
-
* CLI_VERSION is the version of ph-clint-cli itself (read from its own
|
|
16
|
-
* package.json at startup). Since all framework packages share a lockstep
|
|
17
|
-
* version, this is also the correct base for the dependency range.
|
|
18
|
-
*
|
|
19
|
-
* Examples:
|
|
20
|
-
* "0.1.0" → "^0.1.0" (production — stable only)
|
|
21
|
-
* "0.1.0-staging.2" → "^0.1.0-staging.0" (staging + stable)
|
|
22
|
-
* "0.1.0-dev.4" → "^0.1.0-dev.0" (dev + staging + stable)
|
|
23
|
-
*
|
|
24
|
-
* This works because semver orders prereleases alphabetically:
|
|
25
|
-
* dev.N < staging.N < release. A caret range starting at dev.0 naturally
|
|
26
|
-
* upgrades through staging to production.
|
|
27
|
-
*/
|
|
28
|
-
function phClintRange(version) {
|
|
29
|
-
const match = /^(\d+\.\d+\.\d+)(?:-([a-z]+)\.\d+)?/.exec(version);
|
|
30
|
-
if (!match)
|
|
31
|
-
return `^${version}`;
|
|
32
|
-
const base = match[1];
|
|
33
|
-
const channel = match[2]; // "dev", "staging", or undefined
|
|
34
|
-
return channel ? `^${base}-${channel}.0` : `^${base}`;
|
|
35
|
-
}
|
|
36
|
-
/** Version range for @powerhousedao/ph-clint{,-dev} deps in scaffolded projects. */
|
|
37
|
-
const PH_CLINT_VERSION = phClintRange(CLI_VERSION);
|
|
38
|
-
const POWERHOUSE_VERSION = '6.0.0-dev.170';
|
|
39
|
-
export function buildCliPackageJson(spec) {
|
|
40
|
-
const { mastra, powerhouse } = spec.features;
|
|
41
|
-
const pkgName = powerhouse.enabled
|
|
42
|
-
? `${getPackageName(spec)}-cli`
|
|
43
|
-
: getPackageName(spec);
|
|
44
|
-
const bin = getBinName(spec);
|
|
45
|
-
const dependencies = {
|
|
46
|
-
'@powerhousedao/ph-clint': PH_CLINT_VERSION,
|
|
47
|
-
zod: '^4.3.6',
|
|
48
|
-
};
|
|
49
|
-
if (mastra.enabled) {
|
|
50
|
-
dependencies['@mastra/core'] = '^1.22.0';
|
|
51
|
-
dependencies['@mastra/libsql'] = '^1.7.4';
|
|
52
|
-
dependencies['@mastra/memory'] = '^1.13.1';
|
|
53
|
-
}
|
|
54
|
-
if (powerhouse.enabled) {
|
|
55
|
-
dependencies[`${spec.name}-app`] = `file:../${spec.name}-app`;
|
|
56
|
-
dependencies['@powerhousedao/reactor'] = POWERHOUSE_VERSION;
|
|
57
|
-
dependencies['@powerhousedao/reactor-api'] = POWERHOUSE_VERSION;
|
|
58
|
-
dependencies['@powerhousedao/shared'] = POWERHOUSE_VERSION;
|
|
59
|
-
dependencies['document-model'] = POWERHOUSE_VERSION;
|
|
60
|
-
}
|
|
61
|
-
const scripts = {
|
|
62
|
-
'build:skills': 'tsx scripts/build-skills.ts',
|
|
63
|
-
build: 'pnpm build:skills && tsc',
|
|
64
|
-
dev: 'tsx src/main.ts',
|
|
65
|
-
start: 'node dist/main.js',
|
|
66
|
-
test: "NODE_OPTIONS='--experimental-vm-modules' jest --detectOpenHandles",
|
|
67
|
-
lint: 'eslint src',
|
|
68
|
-
};
|
|
69
|
-
if (mastra.enabled) {
|
|
70
|
-
scripts['mastra:dev'] = 'mastra dev';
|
|
71
|
-
scripts['mastra:build'] = 'mastra build';
|
|
72
|
-
scripts['mastra:start'] = 'mastra start';
|
|
73
|
-
}
|
|
74
|
-
const pkg = {
|
|
75
|
-
name: pkgName,
|
|
76
|
-
version: spec.version,
|
|
77
|
-
private: true,
|
|
78
|
-
type: 'module',
|
|
79
|
-
};
|
|
80
|
-
if (spec.description)
|
|
81
|
-
pkg.description = spec.description;
|
|
82
|
-
pkg.bin = { [bin]: './dist/main.js' };
|
|
83
|
-
pkg.scripts = scripts;
|
|
84
|
-
pkg.dependencies = dependencies;
|
|
85
|
-
pkg.devDependencies = {
|
|
86
|
-
'@jest/globals': '^30.2.0',
|
|
87
|
-
'@types/node': '^25.5.2',
|
|
88
|
-
jest: '^30.2.0',
|
|
89
|
-
'@powerhousedao/ph-clint-dev': PH_CLINT_VERSION,
|
|
90
|
-
'ts-jest': '^29.4.6',
|
|
91
|
-
tsx: '^4.19.0',
|
|
92
|
-
typescript: '^6.0.2',
|
|
93
|
-
};
|
|
94
|
-
pkg.engines = { node: '>=22.13.0' };
|
|
95
|
-
return JSON.stringify(pkg, null, 2) + '\n';
|
|
96
|
-
}
|