@powerhousedao/ph-clint-cli 0.1.0-dev.8 → 0.1.0-dev.80
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 +46 -0
- package/dist/codegen/actions.js +424 -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.js +46 -14
- package/dist/codegen/builders/cli-ts.js +87 -49
- 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 +10 -2
- package/dist/codegen/builders/index.js +30 -6
- 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/readme-md.js +7 -6
- package/dist/codegen/builders/root-package-json.js +11 -12
- 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 +0 -18
- package/dist/codegen/exec.js +0 -27
- package/dist/codegen/generated.d.ts +17 -0
- package/dist/codegen/generated.js +49 -0
- package/dist/codegen/index.d.ts +8 -36
- package/dist/codegen/index.js +6 -293
- package/dist/codegen/scaffold.d.ts +41 -3
- package/dist/codegen/scaffold.js +106 -16
- 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 +128 -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/skills/sync.d.ts +40 -0
- package/dist/skills/sync.js +119 -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 +13 -18
- package/dist/codegen/builders/publish-config-ts.d.ts +0 -6
- package/dist/codegen/builders/publish-config-ts.js +0 -18
- 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
package/dist/framework.gen.d.ts
CHANGED
|
@@ -6,23 +6,63 @@ export declare const registry: import("@powerhousedao/ph-clint").InferRegistry<r
|
|
|
6
6
|
readonly version: 1;
|
|
7
7
|
readonly reducer: import("document-model").Reducer<import("@powerhousedao/ph-clint-app").PhClintProjectPHState>;
|
|
8
8
|
readonly actions: {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
setAgentModel: (input: import("@powerhousedao/ph-clint-app").SetAgentModelInput) => import("@powerhousedao/ph-clint-app").SetAgentModelAction;
|
|
10
|
+
addAgentProfileRef: (input: import("@powerhousedao/ph-clint-app").AddAgentProfileRefInput) => import("@powerhousedao/ph-clint-app").AddAgentProfileRefAction;
|
|
11
|
+
removeAgentProfileRef: (input: import("@powerhousedao/ph-clint-app").RemoveAgentProfileRefInput) => import("@powerhousedao/ph-clint-app").RemoveAgentProfileRefAction;
|
|
12
|
+
reorderAgentProfileRefs: (input: import("@powerhousedao/ph-clint-app").ReorderAgentProfileRefsInput) => import("@powerhousedao/ph-clint-app").ReorderAgentProfileRefsAction;
|
|
13
|
+
addAgentSkill: (input: import("@powerhousedao/ph-clint-app").AddAgentSkillInput) => import("@powerhousedao/ph-clint-app").AddAgentSkillAction;
|
|
14
|
+
removeAgentSkill: (input: import("@powerhousedao/ph-clint-app").RemoveAgentSkillInput) => import("@powerhousedao/ph-clint-app").RemoveAgentSkillAction;
|
|
15
|
+
addAgentToolPattern: (input: import("@powerhousedao/ph-clint-app").AddAgentToolPatternInput) => import("@powerhousedao/ph-clint-app").AddAgentToolPatternAction;
|
|
16
|
+
removeAgentToolPattern: (input: import("@powerhousedao/ph-clint-app").RemoveAgentToolPatternInput) => import("@powerhousedao/ph-clint-app").RemoveAgentToolPatternAction;
|
|
17
|
+
addSubAgent: (input: import("@powerhousedao/ph-clint-app").AddSubAgentInput) => import("@powerhousedao/ph-clint-app").AddSubAgentAction;
|
|
18
|
+
removeSubAgent: (input: import("@powerhousedao/ph-clint-app").RemoveSubAgentInput) => import("@powerhousedao/ph-clint-app").RemoveSubAgentAction;
|
|
19
|
+
setSubAgentName: (input: import("@powerhousedao/ph-clint-app").SetSubAgentNameInput) => import("@powerhousedao/ph-clint-app").SetSubAgentNameAction;
|
|
20
|
+
setSubAgentDescription: (input: import("@powerhousedao/ph-clint-app").SetSubAgentDescriptionInput) => import("@powerhousedao/ph-clint-app").SetSubAgentDescriptionAction;
|
|
21
|
+
setMainAgentName: (input: import("@powerhousedao/ph-clint-app").SetMainAgentNameInput) => import("@powerhousedao/ph-clint-app").SetMainAgentNameAction;
|
|
22
|
+
setMainAgentDescription: (input: import("@powerhousedao/ph-clint-app").SetMainAgentDescriptionInput) => import("@powerhousedao/ph-clint-app").SetMainAgentDescriptionAction;
|
|
23
|
+
clearMainAgentDescription: (input: import("@powerhousedao/ph-clint-app").ClearMainAgentDescriptionInput) => import("@powerhousedao/ph-clint-app").ClearMainAgentDescriptionAction;
|
|
24
|
+
setMainAgentImage: (input: import("@powerhousedao/ph-clint-app").SetMainAgentImageInput) => import("@powerhousedao/ph-clint-app").SetMainAgentImageAction;
|
|
25
|
+
clearMainAgentImage: (input: import("@powerhousedao/ph-clint-app").ClearMainAgentImageInput) => import("@powerhousedao/ph-clint-app").ClearMainAgentImageAction;
|
|
26
|
+
addProfile: (input: import("@powerhousedao/ph-clint-app").AddProfileInput) => import("@powerhousedao/ph-clint-app").AddProfileAction;
|
|
27
|
+
updateProfile: (input: import("@powerhousedao/ph-clint-app").UpdateProfileInput) => import("@powerhousedao/ph-clint-app").UpdateProfileAction;
|
|
28
|
+
removeProfile: (input: import("@powerhousedao/ph-clint-app").RemoveProfileInput) => import("@powerhousedao/ph-clint-app").RemoveProfileAction;
|
|
29
|
+
reorderProfiles: (input: import("@powerhousedao/ph-clint-app").ReorderProfilesInput) => import("@powerhousedao/ph-clint-app").ReorderProfilesAction;
|
|
30
|
+
addModel: (input: import("@powerhousedao/ph-clint-app").AddModelInput) => import("@powerhousedao/ph-clint-app").AddModelAction;
|
|
31
|
+
removeModel: (input: import("@powerhousedao/ph-clint-app").RemoveModelInput) => import("@powerhousedao/ph-clint-app").RemoveModelAction;
|
|
11
32
|
enableMastra: (input: import("@powerhousedao/ph-clint-app").EnableMastraInput) => import("@powerhousedao/ph-clint-app").EnableMastraAction;
|
|
12
33
|
disableMastra: (input: import("@powerhousedao/ph-clint-app").DisableMastraInput) => import("@powerhousedao/ph-clint-app").DisableMastraAction;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
34
|
+
setEnableChat: (input: import("@powerhousedao/ph-clint-app").SetEnableChatInput) => import("@powerhousedao/ph-clint-app").SetEnableChatAction;
|
|
35
|
+
addSupportedResource: (input: import("@powerhousedao/ph-clint-app").AddSupportedResourceInput) => import("@powerhousedao/ph-clint-app").AddSupportedResourceAction;
|
|
36
|
+
removeSupportedResource: (input: import("@powerhousedao/ph-clint-app").RemoveSupportedResourceInput) => import("@powerhousedao/ph-clint-app").RemoveSupportedResourceAction;
|
|
37
|
+
setProxyEnabled: (input: import("@powerhousedao/ph-clint-app").SetProxyEnabledInput) => import("@powerhousedao/ph-clint-app").SetProxyEnabledAction;
|
|
38
|
+
setObservabilityEnabled: (input: import("@powerhousedao/ph-clint-app").SetObservabilityEnabledInput) => import("@powerhousedao/ph-clint-app").SetObservabilityEnabledAction;
|
|
39
|
+
importSpec: (input: import("@powerhousedao/ph-clint-app").ImportSpecInput) => import("@powerhousedao/ph-clint-app").ImportSpecAction;
|
|
40
|
+
bumpVersion: (input: import("@powerhousedao/ph-clint-app").BumpVersionInput) => import("@powerhousedao/ph-clint-app").BumpVersionAction;
|
|
41
|
+
publishDev: (input: import("@powerhousedao/ph-clint-app").PublishDevInput) => import("@powerhousedao/ph-clint-app").PublishDevAction;
|
|
42
|
+
publishStaging: (input: import("@powerhousedao/ph-clint-app").PublishStagingInput) => import("@powerhousedao/ph-clint-app").PublishStagingAction;
|
|
43
|
+
publishProduction: (input: import("@powerhousedao/ph-clint-app").PublishProductionInput) => import("@powerhousedao/ph-clint-app").PublishProductionAction;
|
|
44
|
+
setPublishStatus: (input: import("@powerhousedao/ph-clint-app").SetPublishStatusInput) => import("@powerhousedao/ph-clint-app").SetPublishStatusAction;
|
|
45
|
+
addExternalSkill: (input: import("@powerhousedao/ph-clint-app").AddExternalSkillInput) => import("@powerhousedao/ph-clint-app").AddExternalSkillAction;
|
|
46
|
+
removeExternalSkill: (input: import("@powerhousedao/ph-clint-app").RemoveExternalSkillInput) => import("@powerhousedao/ph-clint-app").RemoveExternalSkillAction;
|
|
47
|
+
setExternalSkillName: (input: import("@powerhousedao/ph-clint-app").SetExternalSkillNameInput) => import("@powerhousedao/ph-clint-app").SetExternalSkillNameAction;
|
|
48
|
+
setExternalSkillGithubUrl: (input: import("@powerhousedao/ph-clint-app").SetExternalSkillGithubUrlInput) => import("@powerhousedao/ph-clint-app").SetExternalSkillGithubUrlAction;
|
|
49
|
+
addPowerhousePackage: (input: import("@powerhousedao/ph-clint-app").AddPowerhousePackageInput) => import("@powerhousedao/ph-clint-app").AddPowerhousePackageAction;
|
|
50
|
+
removePowerhousePackage: (input: import("@powerhousedao/ph-clint-app").RemovePowerhousePackageInput) => import("@powerhousedao/ph-clint-app").RemovePowerhousePackageAction;
|
|
51
|
+
addPackageDocumentType: (input: import("@powerhousedao/ph-clint-app").AddPackageDocumentTypeInput) => import("@powerhousedao/ph-clint-app").AddPackageDocumentTypeAction;
|
|
52
|
+
removePackageDocumentType: (input: import("@powerhousedao/ph-clint-app").RemovePackageDocumentTypeInput) => import("@powerhousedao/ph-clint-app").RemovePackageDocumentTypeAction;
|
|
53
|
+
setPackageVersion: (input: import("@powerhousedao/ph-clint-app").SetPackageVersionInput) => import("@powerhousedao/ph-clint-app").SetPackageVersionAction;
|
|
54
|
+
enableRoutine: (input: import("@powerhousedao/ph-clint-app").EnableRoutineInput) => import("@powerhousedao/ph-clint-app").EnableRoutineAction;
|
|
55
|
+
disableRoutine: (input: import("@powerhousedao/ph-clint-app").DisableRoutineInput) => import("@powerhousedao/ph-clint-app").DisableRoutineAction;
|
|
56
|
+
setPowerhouseLevel: (input: import("@powerhousedao/ph-clint-app").SetPowerhouseLevelInput) => import("@powerhousedao/ph-clint-app").SetPowerhouseLevelAction;
|
|
19
57
|
setDescription: (input: import("@powerhousedao/ph-clint-app").SetDescriptionInput) => import("@powerhousedao/ph-clint-app").SetDescriptionAction;
|
|
20
58
|
setVersion: (input: import("@powerhousedao/ph-clint-app").SetVersionInput) => import("@powerhousedao/ph-clint-app").SetVersionAction;
|
|
21
|
-
|
|
22
|
-
setScope: (input: import("@powerhousedao/ph-clint-app").SetScopeInput) => import("@powerhousedao/ph-clint-app").SetScopeAction;
|
|
59
|
+
setPackageIdentifier: (input: import("@powerhousedao/ph-clint-app").SetPackageIdentifierInput) => import("@powerhousedao/ph-clint-app").SetPackageIdentifierAction;
|
|
23
60
|
setName: (name: string | {
|
|
24
61
|
name: string;
|
|
25
62
|
}) => import("document-model").SetNameAction;
|
|
63
|
+
setPreferredEditor: (input: string | null | {
|
|
64
|
+
preferredEditor: string | null;
|
|
65
|
+
}) => import("document-model").SetPreferredEditorAction;
|
|
26
66
|
undo: (count?: number, scope?: string) => import("document-model").UndoAction;
|
|
27
67
|
redo: (count?: number, scope?: string) => import("document-model").RedoAction;
|
|
28
68
|
prune: (start?: number, end?: number, scope?: string) => import("document-model").SchemaPruneAction;
|
package/dist/framework.js
CHANGED
|
@@ -23,12 +23,8 @@ export const configSchema = z.object({
|
|
|
23
23
|
.describe('Port reserved for the impl project (Service B) `pnpm dev`'),
|
|
24
24
|
phVersion: z
|
|
25
25
|
.string()
|
|
26
|
-
.default('
|
|
26
|
+
.default('latest')
|
|
27
27
|
.describe('Pinned Powerhouse version used when emitting a new impl project'),
|
|
28
|
-
projectDocumentId: z
|
|
29
|
-
.string()
|
|
30
|
-
.optional()
|
|
31
|
-
.describe('ID of the powerhouse/ph-clint-project document that drives codegen (set on first regen; edit to switch projects)'),
|
|
32
28
|
});
|
|
33
29
|
export const secretsSchema = z.object({
|
|
34
30
|
apiKey: z.string().optional().describe('Anthropic API key'),
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
## API Reference: CLI Setup
|
|
2
|
+
|
|
3
|
+
### `defineCli<TSchema, TSecrets>(options): Cli`
|
|
4
|
+
|
|
5
|
+
Factory function that creates a CLI from a declarative options object. Two generic type parameters:
|
|
6
|
+
|
|
7
|
+
- `TSchema extends z.ZodType` — config schema type (defaults to `Record<string, unknown>`)
|
|
8
|
+
- `TSecrets extends z.ZodType` — secrets schema type (defaults to `Record<string, unknown>`)
|
|
9
|
+
|
|
10
|
+
### `CliOptions<TSchema, TSecrets>` Interface
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
interface CliOptions<TSchema, TSecrets> {
|
|
14
|
+
name: string; // CLI name (kebab-case, used for config files and env var prefix)
|
|
15
|
+
version: string; // Semantic version (shown in --version)
|
|
16
|
+
root?: string; // Absolute path to package root (resolves sibling packages)
|
|
17
|
+
description: Resolvable<string, Config>; // Static string or function of ({ config, workdir })
|
|
18
|
+
commands: Command<any, any, any>[]; // Array of command definitions
|
|
19
|
+
configSchema?: TSchema; // Zod schema for user-facing config
|
|
20
|
+
secretsSchema?: TSecrets; // Zod schema for sensitive config (API keys, tokens)
|
|
21
|
+
interactive?: InteractiveConfig<Config>; // REPL configuration
|
|
22
|
+
triggers?: Trigger<any, any, any>[]; // Routine loop triggers
|
|
23
|
+
routine?: RoutineConfig; // Routine loop timing & project scanner
|
|
24
|
+
services?: ServiceDefinition<Config>[]; // Background service definitions
|
|
25
|
+
events?: Record<string, (data: any, log: Logger) => void>; // Event handlers
|
|
26
|
+
workdir?: string; // Implementation-level workdir override (hides --workdir flag)
|
|
27
|
+
configDefaults?: Record<string, unknown>; // Layer 5 config defaults
|
|
28
|
+
prompts?: PromptsConfig; // Agent skills & profiles
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### `InteractiveConfig<TConfig>` Interface
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
interface InteractiveConfig<TConfig> {
|
|
36
|
+
welcome: Resolvable<string, TConfig>; // Welcome message (static or dynamic)
|
|
37
|
+
outputWindow?: number; // Trailing output lines in REPL (default: 6)
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### `Resolvable<T, TConfig>` Type
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
type Resolvable<T, TConfig> = T | ((ctx: { workdir: string; config: TConfig }) => T);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Allows static values OR dynamic computation based on resolved workdir and config.
|
|
48
|
+
|
|
49
|
+
### `Cli` Object Interface
|
|
50
|
+
|
|
51
|
+
Methods available on the object returned by `defineCli()`:
|
|
52
|
+
|
|
53
|
+
| Method | Signature | Description |
|
|
54
|
+
|--------|-----------|-------------|
|
|
55
|
+
| `run` | `(argv: string[], options?: RunOptions) => Promise<void>` | Main entry point — parse args, dispatch command or start REPL |
|
|
56
|
+
| `bootstrap` | `(opts?: BootstrapOptions) => Promise<BootstrapResult>` | Initialize runtime without dispatch — for programmatic access |
|
|
57
|
+
| `execute` | `(commandId, args, context?) => Promise<unknown>` | Execute a command directly (programmatic use) |
|
|
58
|
+
| `parseArgs` | `(commandId, argv) => Record<string, unknown>` | Parse CLI argv for a specific command |
|
|
59
|
+
| `getCommand` | `(id: string) => Command \| undefined` | Look up a registered command |
|
|
60
|
+
| `listCommands` | `() => Command[]` | List all registered commands |
|
|
61
|
+
| `generateHelp` | `() => string` | Generate CLI help text |
|
|
62
|
+
| `generateCommandHelp` | `(commandId: string) => string` | Generate help for a specific command |
|
|
63
|
+
| `generateCompletion` | `(shell: string) => string` | Generate shell completion script (bash/zsh/fish) |
|
|
64
|
+
| `configEnvVars` | `() => ConfigEnvVar[]` | List config env var mappings |
|
|
65
|
+
| `getMetadata` | `() => CliMetadata` | JSON-serializable CLI metadata |
|
|
66
|
+
| `configureAgent` | `(loader: AgentLoader<any>) => void` | Set the agent factory (lazy-loaded) |
|
|
67
|
+
| `configureReactor` | `(config: ReactorConfiguration) => void` | Set the reactor configuration (lazy-loaded) |
|
|
68
|
+
|
|
69
|
+
Properties:
|
|
70
|
+
|
|
71
|
+
| Property | Type | Description |
|
|
72
|
+
|----------|------|-------------|
|
|
73
|
+
| `name` | `string` | CLI name |
|
|
74
|
+
| `version` | `string` | CLI version |
|
|
75
|
+
| `description` | `string` | CLI description |
|
|
76
|
+
| `hasAgent` | `boolean` | True when `configureAgent()` has been called |
|
|
77
|
+
| `hasReactor` | `boolean` | True when `configureReactor()` has been called |
|
|
78
|
+
|
|
79
|
+
### `RunOptions` Interface
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
interface RunOptions {
|
|
83
|
+
exit?: (code: number) => void; // Override process.exit (for testing)
|
|
84
|
+
stdout?: (message: string) => void; // Capture stdout
|
|
85
|
+
stderr?: (message: string) => void; // Capture stderr
|
|
86
|
+
interactiveInput?: AsyncIterable<string>; // Headless REPL input (for testing)
|
|
87
|
+
resume?: string; // Resume agent conversation by thread ID
|
|
88
|
+
workdir?: string; // Override workdir (for testing)
|
|
89
|
+
configFile?: string; // --config flag value
|
|
90
|
+
logLevel?: LogLevel; // Override log verbosity (default: 'info')
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `BootstrapOptions` & `BootstrapResult`
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
interface BootstrapOptions {
|
|
98
|
+
workdir?: string; // Explicit workdir (skips flag/cwd logic)
|
|
99
|
+
configFile?: string; // Config file override
|
|
100
|
+
logLevel?: LogLevel; // Log level (default: 'info')
|
|
101
|
+
stdout?: (text: string) => void;
|
|
102
|
+
stderr?: (text: string) => void;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
interface BootstrapResult {
|
|
106
|
+
workdir: string;
|
|
107
|
+
config: Record<string, unknown>;
|
|
108
|
+
context: CommandContext;
|
|
109
|
+
getAgent(): Promise<AgentProvider | undefined>;
|
|
110
|
+
get mastraAgent(): Promise<unknown | undefined>;
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Built-in Commands (Auto-Injected)
|
|
115
|
+
|
|
116
|
+
| Command ID | Condition | Purpose |
|
|
117
|
+
|-----------|-----------|---------|
|
|
118
|
+
| `cli-docs` | Always | Show CLI help (also usable as agent tool) |
|
|
119
|
+
| `config` | When `configSchema` provided | View/modify configuration settings |
|
|
120
|
+
| `{service-id}-start` | Per service definition | Start a background service |
|
|
121
|
+
| `{service-id}-stop` | Per service definition | Stop a running service |
|
|
122
|
+
| `{service-id}-restart` | Per service definition | Restart a service |
|
|
123
|
+
| `{service-id}-ps` | Per service definition | Show service status |
|
|
124
|
+
| `{service-id}-logs` | Per service definition | Tail service logs |
|
|
125
|
+
| `{service-id}-manage` | Per service definition | Interactive management (REPL only) |
|
|
126
|
+
| `{service-id}-ls` | Per service + projectScanner | List discovered projects |
|
|
127
|
+
|
|
128
|
+
### `readPackageInfo(importMetaUrl)`
|
|
129
|
+
|
|
130
|
+
Utility to read name and version from the nearest `package.json`:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import { readPackageInfo } from '@powerhousedao/ph-clint';
|
|
134
|
+
const { name, version } = readPackageInfo(import.meta.url);
|
|
135
|
+
```
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cli-setup
|
|
3
|
+
description: "Set up a new CLI with defineCli, config schemas, entrypoint, and interactive mode"
|
|
4
|
+
metadata:
|
|
5
|
+
author: Powerhouse
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
=== BEGIN SKILL BRIEFING ===
|
|
10
|
+
|
|
11
|
+
IMPORTANT: Don't take any action yet. You will be guided through your tasks after the briefing(s). Just process and confirm your understanding.
|
|
12
|
+
|
|
13
|
+
# CLI Setup - Skill Preamble
|
|
14
|
+
|
|
15
|
+
With this skill, you can scaffold or extend a `defineCli()` configuration — the composition root that wires commands, config, services, triggers, and integrations into a single CLI runtime. A single `defineCli()` call produces a CLI that works in command mode (`mycli cmd --arg val`), interactive REPL mode (`/cmd --arg val`), and as an MCP server — all from the same code.
|
|
16
|
+
|
|
17
|
+
## Core Principles
|
|
18
|
+
|
|
19
|
+
### defineCli Is Declarative
|
|
20
|
+
|
|
21
|
+
You describe _what_ the CLI has — the framework wires it up. The order of options doesn't matter, but understanding what triggers what does:
|
|
22
|
+
|
|
23
|
+
- `configSchema` present → auto-injects a `config` command for viewing/modifying settings
|
|
24
|
+
- `secretsSchema` present → fields merge into configSchema internally, but are censored in output
|
|
25
|
+
- `services` present → auto-injects per-service management commands (`{id}-start`, `{id}-stop`, etc.)
|
|
26
|
+
- `interactive` present → enables the `-i` flag for REPL mode
|
|
27
|
+
- `triggers` present → enables routine loop
|
|
28
|
+
- `cli-docs` command is always auto-injected (CLI help for the agent)
|
|
29
|
+
|
|
30
|
+
### Resolvable Values
|
|
31
|
+
|
|
32
|
+
`description` and `interactive.welcome` accept either a static string or a function `({ config, workdir }) => string`. Use functions when the message depends on runtime state — e.g., showing "demo mode" vs "LLM mode" based on whether an API key is configured.
|
|
33
|
+
|
|
34
|
+
### The Cli Object
|
|
35
|
+
|
|
36
|
+
`defineCli()` returns a `Cli` object — the public API with methods for running, testing, introspection, and metadata. The standard entry point is `cli.run(process.argv)`. For programmatic access (e.g., codegen scripts), use `cli.bootstrap()` which resolves workdir, config, and context without entering the dispatch loop.
|
|
37
|
+
|
|
38
|
+
### Two Interaction Modes
|
|
39
|
+
|
|
40
|
+
1. **Command mode** (headless): Execute one subcommand, then exit. Triggered by `mycli cmd --flag val`.
|
|
41
|
+
2. **Interactive REPL mode**: Persistent session with `/command` syntax and bare text for the default subcommand (typically the agent). Triggered by `mycli -i` or when keep-alive features are active (routine loop, API server).
|
|
42
|
+
|
|
43
|
+
### 6-Layer Config Resolution
|
|
44
|
+
|
|
45
|
+
Config values are resolved in this priority order (highest wins):
|
|
46
|
+
1. `--config <file>` flag
|
|
47
|
+
2. Environment variables: `{CLI_NAME}_{UPPER_SNAKE_FIELD}`
|
|
48
|
+
3. Local config: `{workdir}/.ph/{cliName}.config.local.json`
|
|
49
|
+
4. User config: `~/.ph/{cliName}.config.user.json`
|
|
50
|
+
5. Implementation defaults: `configDefaults` in CliOptions
|
|
51
|
+
6. Zod schema `.default()` values
|
|
52
|
+
|
|
53
|
+
### Config vs Secrets
|
|
54
|
+
|
|
55
|
+
- `configSchema` — user-facing settings (model name, ports, feature flags). Shown in `config` command output.
|
|
56
|
+
- `secretsSchema` — sensitive values (API keys, tokens). Merged into configSchema internally but censored as `***` in output unless `--revealSecrets` is used.
|
|
57
|
+
|
|
58
|
+
Put API keys and tokens in `secretsSchema`, not `configSchema`.
|
|
59
|
+
|
|
60
|
+
### configDefaults vs Schema Defaults
|
|
61
|
+
|
|
62
|
+
- `.default(value)` in the Zod schema → layer 6, the fallback when nothing else is configured
|
|
63
|
+
- `configDefaults` in CliOptions → layer 5, implementation-level overrides that sit above schema defaults but below user/local config
|
|
64
|
+
|
|
65
|
+
Use schema `.default()` for universal sensible defaults. Use `configDefaults` for implementation-specific overrides that differ from the general-purpose default.
|
|
66
|
+
|
|
67
|
+
### Entry Point Convention
|
|
68
|
+
|
|
69
|
+
The CLI entry point is a TypeScript file with a Node.js shebang:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
#!/usr/bin/env node
|
|
73
|
+
import { defineCli } from '@powerhousedao/ph-clint';
|
|
74
|
+
// ... imports ...
|
|
75
|
+
const cli = defineCli({ /* options */ });
|
|
76
|
+
cli.run(process.argv);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The `package.json` needs a `"bin"` field pointing to the compiled output and `"type": "module"` for ESM.
|
|
80
|
+
|
|
81
|
+
## Common Pitfalls
|
|
82
|
+
|
|
83
|
+
- **Forgetting `version`** — Commander needs it for the `--version` flag; omitting it breaks help output
|
|
84
|
+
- **Putting secrets in `configSchema`** — they show up in `config` command output and metadata, exposing sensitive values
|
|
85
|
+
- **Not setting `interactive.welcome`** — REPL starts with no context, confusing the user
|
|
86
|
+
- **Using `configDefaults` for universal defaults** — use `.default()` in the schema instead; `configDefaults` is for implementation-level overrides only
|
|
87
|
+
- **Calling `configureAgent()` inside `defineCli()`** — it's a method on the returned `Cli` object, called after definition
|
|
88
|
+
- **Forgetting `"type": "module"` in package.json** — ESM imports fail at runtime
|
|
89
|
+
- **Not exporting the `cli` object** — other files (e.g., `mastra/index.ts`) may need it for `cli.bootstrap()`
|
|
90
|
+
|
|
91
|
+
## When to Use `createTypes()`
|
|
92
|
+
|
|
93
|
+
For projects with a config schema, use the typed factory to get automatic config typing in all commands:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { createTypes } from '@powerhousedao/ph-clint';
|
|
97
|
+
const { defineCommand, defineTrigger } = createTypes({ configSchema });
|
|
98
|
+
// context.config is now fully typed in every command
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Codegen-Managed Projects
|
|
102
|
+
|
|
103
|
+
In ph-clint-cli projects, `clint-project-init` generates the initial scaffold including `cli.ts` with `@clint:begin`/`@clint:end` marker regions. The codegen system:
|
|
104
|
+
|
|
105
|
+
- **Generates `cli.ts`** with marker regions for imports, commands, services, triggers, prompts, events, interactive, reactor, and mastra
|
|
106
|
+
- **Generates `framework.gen.ts`** (codegen-owned) with the document registry — regenerated when the spec's `documentTypes` change
|
|
107
|
+
- **Emits `framework.ts`** once (user-owned) with `configSchema`, `secretsSchema`, and `createTypes()` — never overwritten after creation
|
|
108
|
+
|
|
109
|
+
**The agent never hand-edits marker regions in `cli.ts`.** To add or change CLI features:
|
|
110
|
+
|
|
111
|
+
1. Update `project-spec.json` to declare the new structure
|
|
112
|
+
2. Run `clint-project-regen` to regenerate the marker regions
|
|
113
|
+
3. Run `clint-project-build` to verify
|
|
114
|
+
|
|
115
|
+
User-owned code outside markers (`configSchema`, `secretsSchema`, `CLI_NAME`) is preserved across regens. User-owned files (`framework.ts`, `src/commands/*.ts`, `src/services/*.ts`, `src/triggers/*.ts`) are never overwritten.
|
|
116
|
+
|
|
117
|
+
=== END OF SKILL BRIEFING ===
|
|
118
|
+
|
|
119
|
+
## Specific tasks
|
|
120
|
+
|
|
121
|
+
* **Assess Cli Needs** [references/00.assess-cli-needs.md](references/00.assess-cli-needs.md)
|
|
122
|
+
* **Define Config Schema** [references/01.define-config-schema.md](references/01.define-config-schema.md)
|
|
123
|
+
* **Wire Cli** [references/02.wire-cli.md](references/02.wire-cli.md)
|
|
124
|
+
* **Add Entrypoint** [references/03.add-entrypoint.md](references/03.add-entrypoint.md)
|
|
125
|
+
* **Expected Outcome** [references/expected-outcome.md](references/expected-outcome.md)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Phase 0: Assess CLI Needs
|
|
2
|
+
|
|
3
|
+
Before writing any code, determine which features the CLI requires.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
### 1. Name the CLI
|
|
8
|
+
|
|
9
|
+
Choose a kebab-case name. This name is used for:
|
|
10
|
+
- Config file paths: `{workdir}/.ph/{name}.config.local.json`
|
|
11
|
+
- Environment variable prefix: `{NAME}_*` (UPPER_SNAKE_CASE)
|
|
12
|
+
- Package `"bin"` field and executable name
|
|
13
|
+
|
|
14
|
+
### 2. Determine version sourcing
|
|
15
|
+
|
|
16
|
+
Choose one:
|
|
17
|
+
- **Hardcoded**: `version: '1.0.0'`
|
|
18
|
+
- **From package.json**: `const { version } = readPackageInfo(import.meta.url)`
|
|
19
|
+
|
|
20
|
+
### 3. Feature checklist
|
|
21
|
+
|
|
22
|
+
For each feature, determine if the CLI needs it:
|
|
23
|
+
|
|
24
|
+
- [ ] **Custom config?** → needs `configSchema` (Zod object)
|
|
25
|
+
- [ ] **Sensitive config (API keys, tokens)?** → needs `secretsSchema` (Zod object)
|
|
26
|
+
- [ ] **Interactive REPL?** → needs `interactive` with `welcome` message
|
|
27
|
+
- [ ] **Background services?** → needs `services` array of `defineService()` definitions
|
|
28
|
+
- [ ] **Automated triggers?** → needs `triggers` array + `routine` config
|
|
29
|
+
- [ ] **AI agent?** → needs `cli.configureAgent(loader)` after `defineCli()`
|
|
30
|
+
- [ ] **Skill templates?** → needs `prompts` config with `artifacts`, `agents`, `skills`
|
|
31
|
+
- [ ] **Powerhouse documents?** → needs `cli.configureReactor(config)` after `defineCli()`
|
|
32
|
+
- [ ] **Service lifecycle events?** → needs `events` handlers
|
|
33
|
+
- [ ] **Implementation-level workdir override?** → needs `workdir` option (hides `--workdir` flag)
|
|
34
|
+
|
|
35
|
+
### 4. List commands to register
|
|
36
|
+
|
|
37
|
+
Enumerate all commands that will be passed to the `commands` array. These should already be defined using `defineCommand()` (see the `command-definition` skill). Note which ones need agent-compatible `{ text, data }` returns.
|
|
38
|
+
|
|
39
|
+
### 5. Detect codegen vs manual project
|
|
40
|
+
|
|
41
|
+
For existing projects, check if `cli.ts` already has `@clint:begin` marker regions:
|
|
42
|
+
- **Codegen-managed**: Markers present — update `project-spec.json` and run `clint-project-regen`. Never hand-edit marker regions.
|
|
43
|
+
- **Manual**: No markers — edit `defineCli()` directly as a regular TypeScript file.
|
|
44
|
+
|
|
45
|
+
For new projects, prefer using `clint-project-init` to generate the scaffold with markers.
|
|
46
|
+
|
|
47
|
+
### 6. Determine config field names
|
|
48
|
+
|
|
49
|
+
For each config/secret field, verify the auto-generated env var name is sensible:
|
|
50
|
+
- Field `apiKey` on CLI `mycli` → env var `MYCLI_API_KEY`
|
|
51
|
+
- Field `connectPort` on CLI `vetra` → env var `VETRA_CONNECT_PORT`
|
|
52
|
+
|
|
53
|
+
If a name would be confusing, consider renaming the field.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Phase 1: Define Config and Secrets Schemas
|
|
2
|
+
|
|
3
|
+
Design and wire the configuration layer. Skip this phase if the CLI needs no configuration.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
### 1. Define configSchema
|
|
8
|
+
|
|
9
|
+
Create a Zod object schema for user-facing settings:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { z } from 'zod';
|
|
13
|
+
|
|
14
|
+
export const configSchema = z.object({
|
|
15
|
+
model: z.string().default('anthropic/claude-sonnet-4-5').describe('LLM model to use'),
|
|
16
|
+
port: z.number().default(4001).describe('Server port'),
|
|
17
|
+
verbose: z.boolean().default(false).describe('Enable verbose output'),
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Rules:
|
|
22
|
+
- Every field MUST have `.describe('...')` — it appears in `config` command output, `--help`, and env var listings
|
|
23
|
+
- Use `.default(value)` for fields with sensible defaults
|
|
24
|
+
- Use `.optional()` only for truly optional fields with no default
|
|
25
|
+
- Prefer specific types: `z.enum([...])` for constrained choices, `z.number()` for ports
|
|
26
|
+
|
|
27
|
+
### 2. Define secretsSchema
|
|
28
|
+
|
|
29
|
+
Create a separate Zod object schema for sensitive values:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
export const secretsSchema = z.object({
|
|
33
|
+
apiKey: z.string().optional().describe('LLM API key'),
|
|
34
|
+
dbToken: z.string().optional().describe('Database access token'),
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Rules:
|
|
39
|
+
- Secrets are almost always `.optional()` — the CLI should work without them (possibly in a degraded mode)
|
|
40
|
+
- These fields are merged into configSchema internally but censored in output
|
|
41
|
+
- They follow the same env var naming: `{CLI_NAME}_{FIELD}`
|
|
42
|
+
|
|
43
|
+
### 3. Set configDefaults (if needed)
|
|
44
|
+
|
|
45
|
+
Use `configDefaults` in `defineCli()` for implementation-specific overrides that differ from the schema defaults:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
defineCli({
|
|
49
|
+
configSchema,
|
|
50
|
+
configDefaults: {
|
|
51
|
+
port: 8080, // This implementation uses 8080, not the schema default of 4001
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This is layer 5 — above schema `.default()` but below user/local config files.
|
|
57
|
+
|
|
58
|
+
### 4. Use createTypes for typed commands
|
|
59
|
+
|
|
60
|
+
If you have a configSchema, create a typed factory so all commands get typed `context.config`:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
// framework.ts
|
|
64
|
+
import { createTypes } from '@powerhousedao/ph-clint';
|
|
65
|
+
import { configSchema, secretsSchema } from './config.js';
|
|
66
|
+
|
|
67
|
+
export const { defineCommand, defineTrigger } = createTypes({ configSchema, secretsSchema });
|
|
68
|
+
export { configSchema, secretsSchema };
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Then import `defineCommand` from `./framework.js` instead of `ph-clint` in all command files.
|
|
72
|
+
|
|
73
|
+
### 5. Verify env var names
|
|
74
|
+
|
|
75
|
+
Run through each field and check the auto-generated env var name:
|
|
76
|
+
- `{CLI_NAME}` is the CLI name uppercased with hyphens replaced by underscores
|
|
77
|
+
- Field keys are converted to UPPER_SNAKE_CASE
|
|
78
|
+
- Example: CLI `my-app`, field `connectPort` → `MY_APP_CONNECT_PORT`
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Phase 2: Wire the defineCli Call
|
|
2
|
+
|
|
3
|
+
Compose the `defineCli()` call with all the options determined in Phase 0.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
### 1. Assemble the core options
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { defineCli } from '@powerhousedao/ph-clint';
|
|
11
|
+
import { configSchema, secretsSchema } from './config.js';
|
|
12
|
+
import { myCommand, otherCommand } from './commands/index.js';
|
|
13
|
+
|
|
14
|
+
export const cli = defineCli({
|
|
15
|
+
name: 'my-app',
|
|
16
|
+
version: '1.0.0',
|
|
17
|
+
description: 'My application CLI',
|
|
18
|
+
commands: [myCommand, otherCommand],
|
|
19
|
+
configSchema,
|
|
20
|
+
secretsSchema,
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Always export the `cli` object — other files may need it (e.g., `mastra/index.ts` for `cli.bootstrap()`).
|
|
25
|
+
|
|
26
|
+
### 2. Configure interactive mode
|
|
27
|
+
|
|
28
|
+
Add an `interactive` block if the CLI supports REPL mode:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
interactive: {
|
|
32
|
+
welcome: 'My App CLI — type /help for commands',
|
|
33
|
+
},
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
For dynamic welcome messages that depend on config:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
interactive: {
|
|
40
|
+
welcome: ({ config, workdir }) => {
|
|
41
|
+
const mode = config.apiKey ? config.model : 'demo mode';
|
|
42
|
+
return `My App (${mode})\nWorkdir: ${workdir}`;
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. Add services (if needed)
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { myService } from './services/my-service.js';
|
|
51
|
+
|
|
52
|
+
defineCli({
|
|
53
|
+
// ...
|
|
54
|
+
services: [myService],
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This auto-injects `my-service-start`, `my-service-stop`, `my-service-restart`, `my-service-ps`, `my-service-logs`, and `my-service-manage` commands.
|
|
59
|
+
|
|
60
|
+
### 4. Add event handlers (if needed)
|
|
61
|
+
|
|
62
|
+
Wire lifecycle events for services or custom events:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
events: {
|
|
66
|
+
'service:ready': (event, log) => {
|
|
67
|
+
log.info(`${event.name} is ready`);
|
|
68
|
+
},
|
|
69
|
+
'service:failed': (event, log) => {
|
|
70
|
+
log.error(`${event.name} failed: ${event.error}`);
|
|
71
|
+
},
|
|
72
|
+
'service:stopped': (event, log) => {
|
|
73
|
+
log.info(`${event.name} stopped`);
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Available service events: `service:pattern-matched`, `service:ready`, `service:failed`, `service:restarting`, `service:stopped`. Each receives `(event, log)` where `log` is a structured Logger.
|
|
79
|
+
|
|
80
|
+
### 5. Add prompts config (if skills are needed)
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import path from 'node:path';
|
|
84
|
+
|
|
85
|
+
prompts: {
|
|
86
|
+
artifacts: [path.join(CLI_ROOT, 'gen', 'skills')],
|
|
87
|
+
agents: {
|
|
88
|
+
'my-agent': {
|
|
89
|
+
name: 'MyAgent',
|
|
90
|
+
sections: ['AgentBase.md', 'MySpecialization.md'],
|
|
91
|
+
skills: ['skill-one', 'skill-two'],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
skills: {
|
|
95
|
+
'skill-one': {
|
|
96
|
+
description: 'Description of skill one',
|
|
97
|
+
inputSchema: z.object({
|
|
98
|
+
mode: z.enum(['expert', 'discovery']).default('expert').describe('Interaction mode'),
|
|
99
|
+
}),
|
|
100
|
+
instructionTemplate: 'Use your {{skillId}} skill in {{mode}} mode for: {{prompt}}',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 6. Call configureAgent / configureReactor (if needed)
|
|
107
|
+
|
|
108
|
+
These are called AFTER `defineCli()` — they are methods on the returned `Cli` object:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
export const cli = defineCli({ /* ... */ });
|
|
112
|
+
|
|
113
|
+
// Agent integration (Mastra)
|
|
114
|
+
cli.configureAgent(createAgent);
|
|
115
|
+
|
|
116
|
+
// Reactor integration (Powerhouse)
|
|
117
|
+
cli.configureReactor({
|
|
118
|
+
registry: [/* document models */],
|
|
119
|
+
// ...
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Both are lazy-loaded — the actual agent/reactor is only created when first accessed.
|
|
124
|
+
|
|
125
|
+
### 7. Codegen projects: use spec + regen
|
|
126
|
+
|
|
127
|
+
In codegen-managed projects, do NOT manually edit `cli.ts` marker regions. Instead:
|
|
128
|
+
|
|
129
|
+
1. Update `project-spec.json` with the new features (commands, services, triggers, integrations)
|
|
130
|
+
2. Run `clint-project-regen` to regenerate marker regions
|
|
131
|
+
3. Edit user-owned files directly: `framework.ts` for config/secrets schemas, `src/commands/*.ts` for commands, etc.
|
|
132
|
+
|
|
133
|
+
Core options outside markers (`name`, `version`, `description`, `configSchema`, `secretsSchema`) are in the user-editable zone — edit those directly in `cli.ts`.
|
|
134
|
+
|
|
135
|
+
### 8. Verify built-in commands
|
|
136
|
+
|
|
137
|
+
After wiring, confirm these commands will be auto-injected:
|
|
138
|
+
- `cli-docs` — always present
|
|
139
|
+
- `config` — present if `configSchema` was provided
|
|
140
|
+
- Service commands — present for each entry in `services`
|
|
141
|
+
- Skill commands — present for each entry in `prompts.skills`
|