@powerhousedao/ph-clint-cli 0.1.0-dev.7 → 0.1.0-dev.70
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 +52 -10
- package/dist/codegen/actions.d.ts +1 -0
- package/dist/codegen/actions.js +1 -0
- package/dist/codegen/builders/agent-ts.d.ts +4 -4
- package/dist/codegen/builders/agent-ts.js +92 -2
- package/dist/codegen/builders/app-index-ts.d.ts +3 -10
- package/dist/codegen/builders/app-index-ts.js +30 -20
- package/dist/codegen/builders/cli-package-json.d.ts +1 -8
- package/dist/codegen/builders/cli-package-json.js +1 -96
- package/dist/codegen/builders/cli-ts.js +88 -37
- package/dist/codegen/builders/config-ts.d.ts +1 -1
- package/dist/codegen/builders/config-ts.js +2 -8
- package/dist/codegen/builders/demo-agent-ts.d.ts +8 -0
- package/dist/codegen/builders/demo-agent-ts.js +50 -0
- package/dist/codegen/builders/eslint-config-js.d.ts +1 -1
- package/dist/codegen/builders/eslint-config-js.js +7 -4
- package/dist/codegen/builders/framework-gen-ts.d.ts +11 -6
- package/dist/codegen/builders/framework-gen-ts.js +73 -21
- package/dist/codegen/builders/framework-ts.js +33 -7
- package/dist/codegen/builders/index.d.ts +1 -44
- package/dist/codegen/builders/index.js +1 -61
- package/dist/codegen/builders/manifest-json.d.ts +6 -0
- package/dist/codegen/builders/manifest-json.js +31 -0
- package/dist/codegen/builders/mastra-index-ts.d.ts +3 -0
- package/dist/codegen/builders/mastra-index-ts.js +47 -5
- package/dist/codegen/builders/publish-config-js.d.ts +8 -0
- package/dist/codegen/builders/publish-config-js.js +33 -0
- package/dist/codegen/builders/publish-config-ts.d.ts +4 -2
- package/dist/codegen/builders/publish-config-ts.js +25 -11
- package/dist/codegen/builders/readme-md.js +7 -6
- package/dist/codegen/builders/root-package-json.js +14 -11
- package/dist/codegen/builders/smoke-test-ts.d.ts +2 -0
- package/dist/codegen/builders/smoke-test-ts.js +15 -0
- package/dist/codegen/exec.d.ts +1 -20
- package/dist/codegen/exec.js +1 -41
- package/dist/codegen/generated.d.ts +1 -0
- package/dist/codegen/generated.js +1 -0
- package/dist/codegen/hashes.d.ts +1 -6
- package/dist/codegen/hashes.js +1 -60
- package/dist/codegen/index.d.ts +8 -36
- package/dist/codegen/index.js +6 -293
- package/dist/codegen/markers.d.ts +1 -36
- package/dist/codegen/markers.js +1 -86
- package/dist/codegen/scaffold.d.ts +1 -34
- package/dist/codegen/scaffold.js +1 -60
- package/dist/codegen/write.d.ts +1 -6
- package/dist/codegen/write.js +1 -32
- package/dist/commands/clint-project-build.d.ts +6 -1
- package/dist/commands/clint-project-build.js +11 -28
- package/dist/commands/clint-project-init.d.ts +45 -10
- package/dist/commands/clint-project-init.js +61 -47
- package/dist/commands/clint-project-publish.d.ts +7 -1
- package/dist/commands/clint-project-publish.js +6 -4
- package/dist/commands/clint-project-regen.d.ts +6 -1
- package/dist/commands/clint-project-regen.js +26 -2
- package/dist/commands/clint-skills-sync.d.ts +15 -0
- package/dist/commands/clint-skills-sync.js +56 -0
- package/dist/framework.d.ts +6 -170
- package/dist/framework.gen.d.ts +1 -32
- 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/services/clint-project.js +21 -0
- package/dist/skills/sync.d.ts +1 -0
- package/dist/skills/sync.js +1 -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 +10 -0
- package/dist/triggers/publish-trigger.js +137 -0
- package/dist/triggers/spec-change.d.ts +5 -34
- package/dist/triggers/spec-change.js +137 -102
- package/package.json +12 -17
- package/prompts/skills-ext/.gitkeep +0 -0
- package/prompts/skills-tpl/.gitkeep +0 -0
|
@@ -1,43 +1,14 @@
|
|
|
1
|
+
import type { ImportSpecInput } from '@powerhousedao/ph-clint-app/document-models/ph-clint-project';
|
|
1
2
|
import type { ClintProjectSpec } from '../spec/types.js';
|
|
2
|
-
/** Stable hash of a ClintProjectSpec (sha256 of canonical-key JSON).
|
|
3
|
+
/** Stable hash of a ClintProjectSpec (sha256 of canonical-key JSON).
|
|
4
|
+
* Excludes documentId/documentType — they don't affect codegen output. */
|
|
3
5
|
export declare function hashSpec(spec: ClintProjectSpec): string;
|
|
6
|
+
export declare function specToImportInput(spec: ClintProjectSpec): ImportSpecInput;
|
|
4
7
|
export declare const specChangeTrigger: import("@powerhousedao/ph-clint").Trigger<{
|
|
5
8
|
pending: number;
|
|
6
9
|
}, {
|
|
7
10
|
model: string;
|
|
8
11
|
devServicePort: number;
|
|
9
12
|
phVersion: string;
|
|
10
|
-
projectDocumentId?: string | undefined;
|
|
11
13
|
apiKey?: string | undefined;
|
|
12
|
-
}, import("@powerhousedao/ph-clint").InferRegistry<readonly [
|
|
13
|
-
readonly version: 1;
|
|
14
|
-
readonly reducer: import("document-model").Reducer<import("@powerhousedao/ph-clint-app").PhClintProjectPHState>;
|
|
15
|
-
readonly actions: {
|
|
16
|
-
enableRoutine: (input: import("@powerhousedao/ph-clint-app").EnableRoutineInput) => import("@powerhousedao/ph-clint-app").EnableRoutineAction;
|
|
17
|
-
disableRoutine: (input: import("@powerhousedao/ph-clint-app").DisableRoutineInput) => import("@powerhousedao/ph-clint-app").DisableRoutineAction;
|
|
18
|
-
enableMastra: (input: import("@powerhousedao/ph-clint-app").EnableMastraInput) => import("@powerhousedao/ph-clint-app").EnableMastraAction;
|
|
19
|
-
disableMastra: (input: import("@powerhousedao/ph-clint-app").DisableMastraInput) => import("@powerhousedao/ph-clint-app").DisableMastraAction;
|
|
20
|
-
enablePowerhouse: (input: import("@powerhousedao/ph-clint-app").EnablePowerhouseInput) => import("@powerhousedao/ph-clint-app").EnablePowerhouseAction;
|
|
21
|
-
setPowerhouseSwitchboard: (input: import("@powerhousedao/ph-clint-app").SetPowerhouseSwitchboardInput) => import("@powerhousedao/ph-clint-app").SetPowerhouseSwitchboardAction;
|
|
22
|
-
setPowerhouseConnect: (input: import("@powerhousedao/ph-clint-app").SetPowerhouseConnectInput) => import("@powerhousedao/ph-clint-app").SetPowerhouseConnectAction;
|
|
23
|
-
setPackageName: (input: import("@powerhousedao/ph-clint-app").SetPackageNameInput) => import("@powerhousedao/ph-clint-app").SetPackageNameAction;
|
|
24
|
-
clearBin: (input: import("@powerhousedao/ph-clint-app").ClearBinInput) => import("@powerhousedao/ph-clint-app").ClearBinAction;
|
|
25
|
-
setBin: (input: import("@powerhousedao/ph-clint-app").SetBinInput) => import("@powerhousedao/ph-clint-app").SetBinAction;
|
|
26
|
-
setDescription: (input: import("@powerhousedao/ph-clint-app").SetDescriptionInput) => import("@powerhousedao/ph-clint-app").SetDescriptionAction;
|
|
27
|
-
setVersion: (input: import("@powerhousedao/ph-clint-app").SetVersionInput) => import("@powerhousedao/ph-clint-app").SetVersionAction;
|
|
28
|
-
clearScope: (input: import("@powerhousedao/ph-clint-app").ClearScopeInput) => import("@powerhousedao/ph-clint-app").ClearScopeAction;
|
|
29
|
-
setScope: (input: import("@powerhousedao/ph-clint-app").SetScopeInput) => import("@powerhousedao/ph-clint-app").SetScopeAction;
|
|
30
|
-
setName: (name: string | {
|
|
31
|
-
name: string;
|
|
32
|
-
}) => import("document-model").SetNameAction;
|
|
33
|
-
undo: (count?: number, scope?: string) => import("document-model").UndoAction;
|
|
34
|
-
redo: (count?: number, scope?: string) => import("document-model").RedoAction;
|
|
35
|
-
prune: (start?: number, end?: number, scope?: string) => import("document-model").SchemaPruneAction;
|
|
36
|
-
loadState: <TState extends import("document-model").PHBaseState = import("document-model").PHBaseState>(state: TState & {
|
|
37
|
-
name: string;
|
|
38
|
-
}, operations: number) => import("document-model").LoadStateAction;
|
|
39
|
-
noop: (scope?: string) => import("document-model").NOOPAction;
|
|
40
|
-
};
|
|
41
|
-
readonly utils: import("document-model").DocumentModelUtils<import("@powerhousedao/ph-clint-app").PhClintProjectPHState>;
|
|
42
|
-
readonly documentModel: import("document-model").DocumentModelPHState;
|
|
43
|
-
}]>>;
|
|
14
|
+
}, import("@powerhousedao/ph-clint").InferRegistry<readonly [import("document-model").DocumentModelModule<import("@powerhousedao/ph-clint-app/document-models/ph-clint-project").PhClintProjectPHState>]>>;
|
|
@@ -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,132 @@ function canonicalJson(value) {
|
|
|
70
75
|
.join(',') +
|
|
71
76
|
'}');
|
|
72
77
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
78
|
+
export function specToImportInput(spec) {
|
|
79
|
+
return {
|
|
80
|
+
name: spec.name,
|
|
81
|
+
scope: spec.scope ?? null,
|
|
82
|
+
version: spec.version,
|
|
83
|
+
description: spec.description,
|
|
84
|
+
powerhouse: spec.features.powerhouse,
|
|
85
|
+
mastraEnabled: spec.features.mastra.enabled,
|
|
86
|
+
routineEnabled: spec.features.routine.enabled,
|
|
87
|
+
agentId: spec.features.mastra.agentId ?? null,
|
|
88
|
+
agentName: spec.features.mastra.agentName ?? null,
|
|
89
|
+
models: spec.features.mastra.models.map(m => ({
|
|
90
|
+
id: m.id,
|
|
91
|
+
isDefault: m.isDefault,
|
|
92
|
+
})),
|
|
93
|
+
profiles: spec.features.mastra.profiles.map(p => ({
|
|
94
|
+
id: p.id,
|
|
95
|
+
title: p.title,
|
|
96
|
+
content: p.content,
|
|
97
|
+
})),
|
|
98
|
+
packages: spec.packages.map(p => ({
|
|
99
|
+
id: p.id,
|
|
100
|
+
packageName: p.packageName,
|
|
101
|
+
documentTypes: p.documentTypes,
|
|
102
|
+
})),
|
|
103
|
+
externalSkills: spec.externalSkills.map(s => ({
|
|
104
|
+
id: s.id,
|
|
105
|
+
name: s.name,
|
|
106
|
+
githubUrl: s.githubUrl,
|
|
107
|
+
})),
|
|
108
|
+
agentDescription: spec.features.mastra.agentDescription ?? null,
|
|
109
|
+
agentImage: spec.features.mastra.agentImage ?? null,
|
|
110
|
+
enableChat: spec.features.mastra.common.enableChat,
|
|
111
|
+
proxyEnabled: spec.deployment.proxyEnabled,
|
|
112
|
+
supportedResources: spec.deployment.supportedResources,
|
|
113
|
+
};
|
|
88
114
|
}
|
|
89
115
|
export const specChangeTrigger = createDocumentChangeTrigger({
|
|
90
116
|
id: 'spec-change',
|
|
91
117
|
documentType: DOCUMENT_TYPE,
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
118
|
+
// No documentId → watches ALL ph-clint-project docs
|
|
119
|
+
callOnEmpty: true, // bootstrap from disk when no documents exist yet
|
|
120
|
+
async onChange(docs, ctx) {
|
|
121
|
+
const log = ctx.context.log;
|
|
122
|
+
const folders = ctx.context.folders;
|
|
123
|
+
// Build the mapping: on-disk projects + personal drive documents
|
|
124
|
+
const scanner = clintProject.projectScanner;
|
|
125
|
+
const scanResults = scanner
|
|
126
|
+
? scanProjects(ctx.context.workdir, scanner)
|
|
127
|
+
: [];
|
|
128
|
+
const mapping = await getProjectMapping(scanResults, folders);
|
|
129
|
+
// Auto-create spec documents for unlinked or orphaned projects
|
|
101
130
|
const reactor = await ctx.reactor();
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
131
|
+
if (reactor && folders) {
|
|
132
|
+
for (const entry of mapping) {
|
|
133
|
+
if (!entry.path)
|
|
134
|
+
continue;
|
|
135
|
+
const existingSpec = await readProjectSpec(entry.path);
|
|
136
|
+
if (!existingSpec)
|
|
137
|
+
continue;
|
|
138
|
+
try {
|
|
139
|
+
const { docId, created } = await ensureSpecDocument({
|
|
140
|
+
spec: existingSpec,
|
|
141
|
+
targetDir: entry.path,
|
|
142
|
+
reactor,
|
|
143
|
+
folders,
|
|
144
|
+
});
|
|
145
|
+
if (created) {
|
|
146
|
+
log?.info(`${TAG} linked project ${entry.name} to document ${docId}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
log?.warn(`${TAG} could not ensure spec document for ${entry.name}: ${err instanceof Error ? err.message : String(err)}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
108
153
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
154
|
+
for (const doc of docs) {
|
|
155
|
+
const spec = specFromDocumentState(doc.state.global, {
|
|
156
|
+
documentId: doc.header.id,
|
|
157
|
+
documentType: doc.header.documentType,
|
|
158
|
+
});
|
|
159
|
+
if (!spec) {
|
|
160
|
+
log?.debug(`${TAG} document ${doc.header.id} state did not validate against ClintProjectSpec, skipping`);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
// Find target directory from mapping
|
|
164
|
+
const entry = mapping.find((m) => m.documentId === doc.header.id);
|
|
165
|
+
const targetDir = entry?.path ?? path.join(ctx.context.workdir, spec.name);
|
|
166
|
+
// Per-project hash comparison
|
|
167
|
+
const nextHash = hashSpec(spec);
|
|
168
|
+
const prevHash = await readLastSpecHash(targetDir);
|
|
169
|
+
if (nextHash === prevHash) {
|
|
170
|
+
log?.debug(`${TAG} spec for ${spec.name} unchanged (hash=${nextHash.slice(0, 12)}…), skipping`);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
log?.debug(`${TAG} spec for ${spec.name} changed: ${prevHash ? prevHash.slice(0, 12) + '…' : '<none>'} → ${nextHash.slice(0, 12)}…`);
|
|
174
|
+
log?.info(`${TAG} regenerating ${spec.name} at ${targetDir} (doc=${doc.header.id})`);
|
|
175
|
+
const t0 = Date.now();
|
|
176
|
+
const warnings = [];
|
|
177
|
+
const result = await generateProject({
|
|
178
|
+
targetDir,
|
|
179
|
+
spec,
|
|
180
|
+
mode: 'update',
|
|
181
|
+
force: true,
|
|
182
|
+
onWarn: (m) => warnings.push(m),
|
|
183
|
+
});
|
|
184
|
+
// Write spec JSON with documentId
|
|
185
|
+
await writeProjectSpec(targetDir, spec);
|
|
186
|
+
await writeLastSpecHash(targetDir, nextHash);
|
|
187
|
+
const elapsed = Date.now() - t0;
|
|
188
|
+
if (log) {
|
|
189
|
+
if (result.migrated)
|
|
190
|
+
log.info(`${TAG} migrated flat → split layout`);
|
|
191
|
+
log.info(`${TAG} regenerated ${spec.name} in ${elapsed}ms: ${result.files.length} written, ${result.skipped.length} skipped, ${result.deleted.length} deleted`);
|
|
192
|
+
for (const w of warnings)
|
|
193
|
+
log.warn(`${TAG} ${w}`);
|
|
194
|
+
}
|
|
195
|
+
// Run post-generation actions (ph-init, install, build, skills-sync).
|
|
196
|
+
// Route through ctx.context.stdout so output flows through
|
|
197
|
+
// routine.onOutput → service log buffer → ServicePanel.
|
|
198
|
+
await runPostGenActions(result.pendingActions, {
|
|
199
|
+
log: (msg) => ctx.context.stdout(`${TAG} ${msg}\n`),
|
|
200
|
+
runProcess: ctx.context.runProcess,
|
|
115
201
|
});
|
|
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
202
|
}
|
|
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
|
-
};
|
|
203
|
+
// Work done inline, no additional work item needed
|
|
204
|
+
return null;
|
|
170
205
|
},
|
|
171
206
|
});
|
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.70",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -10,41 +10,36 @@
|
|
|
10
10
|
"ph-clint": "./dist/main.js"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
-
"dist"
|
|
14
|
-
"prompts"
|
|
13
|
+
"dist"
|
|
15
14
|
],
|
|
16
15
|
"scripts": {
|
|
17
16
|
"build:skills": "tsx scripts/build-skills.ts",
|
|
18
17
|
"build": "pnpm build:skills && tsc",
|
|
19
18
|
"dev": "tsx src/main.ts",
|
|
20
19
|
"start": "node dist/main.js",
|
|
21
|
-
"test": "NODE_OPTIONS='--experimental-vm-modules' jest --detectOpenHandles",
|
|
20
|
+
"test": "NODE_OPTIONS='--experimental-vm-modules' jest --detectOpenHandles --coverage",
|
|
21
|
+
"test:e2e": "NODE_OPTIONS='--experimental-vm-modules' jest --detectOpenHandles --testPathPatterns 'tests/(e2e|codegen-e2e)/' --testPathIgnorePatterns '/node_modules/'",
|
|
22
22
|
"lint": "eslint src",
|
|
23
23
|
"mastra:dev": "mastra dev",
|
|
24
24
|
"mastra:build": "mastra build",
|
|
25
25
|
"mastra:start": "mastra start"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@
|
|
29
|
-
"@powerhousedao/ph-clint-app": "^0.1.0-dev.7",
|
|
28
|
+
"@electric-sql/pglite": "0.3.15",
|
|
30
29
|
"@mastra/core": "^1.22.0",
|
|
31
30
|
"@mastra/libsql": "^1.7.4",
|
|
32
31
|
"@mastra/memory": "^1.13.1",
|
|
33
|
-
"@powerhousedao/
|
|
34
|
-
"@powerhousedao/
|
|
35
|
-
"@powerhousedao/
|
|
36
|
-
"@
|
|
37
|
-
"
|
|
32
|
+
"@powerhousedao/ph-clint": "^0.1.0-dev.70",
|
|
33
|
+
"@powerhousedao/ph-clint-app": "^0.1.0-dev.70",
|
|
34
|
+
"@powerhousedao/ph-clint-dev": "^0.1.0-dev.70",
|
|
35
|
+
"@powerhousedao/reactor": "6.0.0-dev.216",
|
|
36
|
+
"@powerhousedao/reactor-api": "6.0.0-dev.216",
|
|
37
|
+
"@powerhousedao/shared": "6.0.0-dev.216",
|
|
38
|
+
"document-model": "6.0.0-dev.216",
|
|
38
39
|
"kysely": "^0.27.0",
|
|
39
40
|
"kysely-pglite-dialect": "^1.3.0",
|
|
40
|
-
"@powerhousedao/ph-clint-dev": "^0.1.0-dev.7",
|
|
41
41
|
"zod": "^4.3.6"
|
|
42
42
|
},
|
|
43
|
-
"pnpm": {
|
|
44
|
-
"overrides": {
|
|
45
|
-
"mastra>@mastra/deployer": "1.22.0"
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
43
|
"devDependencies": {
|
|
49
44
|
"@jest/globals": "^30.2.0",
|
|
50
45
|
"@types/node": "^25.5.2",
|
|
File without changes
|
|
File without changes
|