keystone-cli 1.0.0 → 1.0.2
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/README.md +8 -5
- package/package.json +1 -1
- package/src/db/memory-db.ts +1 -2
- package/src/db/sqlite-setup.ts +2 -3
- package/src/runner/engine-executor.ts +1 -3
- package/src/templates/agents/keystone-architect.md +2 -2
- package/src/templates/batch-processor.yaml +1 -1
- package/src/templates/loop-parallel.yaml +1 -1
- package/src/utils/resource-loader.test.ts +7 -7
package/README.md
CHANGED
|
@@ -133,14 +133,17 @@ keystone ui
|
|
|
133
133
|
|
|
134
134
|
`keystone init` seeds these workflows under `.keystone/workflows/` (and the agents they rely on under `.keystone/workflows/agents/`):
|
|
135
135
|
|
|
136
|
+
Top-level workflows:
|
|
136
137
|
- `scaffold-feature`: Interactive workflow scaffolder. Prompts for requirements, plans files, generates content, and writes them.
|
|
138
|
+
- `decompose-problem`: Decomposes a problem into research/implementation/review tasks, waits for approval, runs sub-workflows, and summarizes.
|
|
139
|
+
- `dev`: Self-bootstrapping DevMode workflow for an interactive plan/implement/verify loop.
|
|
140
|
+
|
|
141
|
+
Sub-workflows:
|
|
137
142
|
- `scaffold-plan`: Generates a file plan from `requirements` input.
|
|
138
143
|
- `scaffold-generate`: Generates file contents from `requirements` plus a `files` plan.
|
|
139
|
-
- `decompose-problem`: Decomposes a problem into research/implementation/review tasks, waits for approval, runs sub-workflows, and summarizes.
|
|
140
144
|
- `decompose-research`: Runs a single research task (`task`) with optional `context`/`constraints`.
|
|
141
145
|
- `decompose-implement`: Runs a single implementation task (`task`) with optional `research` findings.
|
|
142
146
|
- `decompose-review`: Reviews a single implementation task (`task`) with optional `implementation` results.
|
|
143
|
-
- `dev`: Self-bootstrapping DevMode workflow for an interactive plan/implement/verify loop.
|
|
144
147
|
|
|
145
148
|
Example runs:
|
|
146
149
|
```bash
|
|
@@ -148,7 +151,7 @@ keystone run scaffold-feature
|
|
|
148
151
|
keystone run decompose-problem -i problem="Add caching to the API" -i context="Node/Bun service"
|
|
149
152
|
```
|
|
150
153
|
|
|
151
|
-
|
|
154
|
+
Sub-workflows are used by the top-level workflows, but can be run directly if you want just one phase.
|
|
152
155
|
|
|
153
156
|
---
|
|
154
157
|
|
|
@@ -258,7 +261,7 @@ model: claude-3-5-sonnet-latest
|
|
|
258
261
|
```
|
|
259
262
|
|
|
260
263
|
### OpenAI Compatible Providers
|
|
261
|
-
You can add any OpenAI-compatible provider (
|
|
264
|
+
You can add any OpenAI-compatible provider (Together AI, Perplexity, Local Ollama, etc.) by setting the `type` to `openai` and providing the `base_url` and `api_key_env`.
|
|
262
265
|
|
|
263
266
|
### GitHub Copilot Support
|
|
264
267
|
|
|
@@ -476,7 +479,7 @@ All steps support common features:
|
|
|
476
479
|
- `transform`: Post-process output using expressions.
|
|
477
480
|
- `learn`: Auto-index for few-shot.
|
|
478
481
|
- `reflexion`: Self-correction loop.
|
|
479
|
-
- `auto_heal`: LLM-powered automatic error recovery
|
|
482
|
+
- `auto_heal`: LLM-powered automatic error recovery.
|
|
480
483
|
- `inputSchema` / `outputSchema`: JSON Schema validation.
|
|
481
484
|
- `outputRetries`: Max retries for output validation failures.
|
|
482
485
|
- `repairStrategy`: Strategy for output repair (`reask`, `repair`, `hybrid`).
|
package/package.json
CHANGED
package/src/db/memory-db.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Database } from 'bun:sqlite';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { existsSync, mkdirSync } from 'node:fs';
|
|
4
4
|
import { dirname } from 'node:path';
|
|
@@ -24,7 +24,6 @@ export class MemoryDb {
|
|
|
24
24
|
cached.refCount++;
|
|
25
25
|
this.db = cached.db;
|
|
26
26
|
} else {
|
|
27
|
-
const { Database } = require('bun:sqlite');
|
|
28
27
|
const dir = dirname(dbPath);
|
|
29
28
|
if (!existsSync(dir)) {
|
|
30
29
|
mkdirSync(dir, { recursive: true });
|
package/src/db/sqlite-setup.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Database } from 'bun:sqlite';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
1
3
|
import { ConsoleLogger, type Logger } from '../utils/logger.ts';
|
|
2
4
|
|
|
3
5
|
export function setupSqlite(logger: Logger = new ConsoleLogger()) {
|
|
@@ -5,9 +7,6 @@ export function setupSqlite(logger: Logger = new ConsoleLogger()) {
|
|
|
5
7
|
// We need to try to load a custom one (e.g. from Homebrew) if on macOS
|
|
6
8
|
if (process.platform === 'darwin') {
|
|
7
9
|
try {
|
|
8
|
-
const { Database } = require('bun:sqlite');
|
|
9
|
-
const { existsSync } = require('node:fs');
|
|
10
|
-
|
|
11
10
|
// Common Homebrew paths for SQLite
|
|
12
11
|
const paths = [
|
|
13
12
|
'/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib',
|
|
@@ -325,9 +325,7 @@ export async function executeEngineStep(
|
|
|
325
325
|
throw new Error(`Engine command "${command}" is not in the allowlist. Allowed: ${allowedList}`);
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
-
const versionArgs = allowlistMatch.entry.versionArgs
|
|
329
|
-
? allowlistMatch.entry.versionArgs
|
|
330
|
-
: ['--version'];
|
|
328
|
+
const versionArgs = allowlistMatch.entry.versionArgs ?? ['--version'];
|
|
331
329
|
const versionOutput = await checkEngineVersion(command, versionArgs, env, cwd, abortSignal);
|
|
332
330
|
if (!versionOutput.includes(allowlistMatch.entry.version)) {
|
|
333
331
|
throw new Error(
|
|
@@ -12,7 +12,7 @@ You are the Keystone Architect. Your goal is to design and generate high-quality
|
|
|
12
12
|
## Workflow Schema (.yaml)
|
|
13
13
|
- **name**: Unique identifier for the workflow.
|
|
14
14
|
- **description**: (Optional) Description of the workflow.
|
|
15
|
-
- **inputs**: Map of `{ type: 'string'|'number'|'boolean'|'array'|'object', default: any, description
|
|
15
|
+
- **inputs**: Map of `{ type: 'string'|'number'|'boolean'|'array'|'object', default: any, description?: string }` under the `inputs` key.
|
|
16
16
|
- **outputs**: Map of expressions (e.g., `${{ steps.id.output }}`) under the `outputs` key.
|
|
17
17
|
- **outputSchema**: (Optional) JSON Schema for final workflow outputs.
|
|
18
18
|
- **env**: (Optional) Map of workflow-level environment variables.
|
|
@@ -59,7 +59,7 @@ Markdown files with YAML frontmatter:
|
|
|
59
59
|
## Expression Syntax
|
|
60
60
|
- `${{ inputs.name }}`
|
|
61
61
|
- `${{ steps.id.output }}`
|
|
62
|
-
- `${{ steps.id.status }}` (e.g., `'pending'`, `'running'`, `'success'`, `'failed'`, `'skipped'`)
|
|
62
|
+
- `${{ steps.id.status }}` (e.g., `'pending'`, `'running'`, `'success'`, `'failed'`, `'paused'`, `'suspended'`, `'skipped'`, `'canceled'`, `'waiting'`)
|
|
63
63
|
- `${{ args.paramName }}` (used inside agent tools)
|
|
64
64
|
- `${{ item }}` (current item in a `foreach` loop)
|
|
65
65
|
- `${{ secrets.NAME }}` (access redacted secrets)
|
|
@@ -3,7 +3,7 @@ description: "Test the foreach race condition fix and .every() support"
|
|
|
3
3
|
|
|
4
4
|
outputs:
|
|
5
5
|
all_success: ${{ steps.process_items.items.every(s => s.status == 'success') }}
|
|
6
|
-
item_count: ${{ steps.process_items.
|
|
6
|
+
item_count: ${{ steps.process_items.output.length }}
|
|
7
7
|
first_output: ${{ steps.process_items.items[0].output }}
|
|
8
8
|
|
|
9
9
|
steps:
|
|
@@ -39,16 +39,16 @@ describe('ResourceLoader', () => {
|
|
|
39
39
|
expect(ResourceLoader.isDirectory(testFile)).toBe(false);
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
test('should
|
|
42
|
+
test('should expose embedded assets manifest when available', () => {
|
|
43
43
|
const assets = ResourceLoader.getEmbeddedAssets();
|
|
44
44
|
const keys = Object.keys(assets);
|
|
45
|
-
// We expect at least the default seeded workflows if they exist in .keystone
|
|
46
|
-
expect(keys.length).toBeGreaterThan(0);
|
|
47
45
|
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
// Bundled assets only exist in compiled builds; dev/test may be empty.
|
|
47
|
+
if (keys.length === 0) {
|
|
48
|
+
expect(keys.length).toBe(0);
|
|
49
|
+
return;
|
|
52
50
|
}
|
|
51
|
+
|
|
52
|
+
expect(Object.values(assets).every((value) => typeof value === 'string')).toBe(true);
|
|
53
53
|
});
|
|
54
54
|
});
|