owflow 0.2.0 → 0.4.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 +83 -28
- package/dist/agents/code-reviewer.md +1 -1
- package/dist/agents/information-gatherer.md +691 -691
- package/dist/agents/production-readiness-checker.md +1 -1
- package/dist/agents/project-analyzer.md +0 -1
- package/dist/agents/research-planner.md +450 -447
- package/dist/agents/research-synthesizer.md +403 -401
- package/dist/agents/solution-brainstormer.md +257 -257
- package/dist/agents/solution-designer.md +372 -372
- package/dist/agents/task-classifier.md +3 -3
- package/dist/commands/agents-md-generator.md +36 -0
- package/dist/commands/dev-analyze.md +33 -0
- package/dist/commands/dev-bugfix.md +37 -0
- package/dist/commands/dev-finalize.md +33 -0
- package/dist/commands/dev-implement.md +34 -0
- package/dist/commands/dev-plan.md +37 -0
- package/dist/commands/dev-spec.md +37 -0
- package/dist/commands/dev-tdd-red.md +33 -0
- package/dist/commands/dev-verify.md +33 -0
- package/dist/commands/development.md +11 -12
- package/dist/commands/diagrams-mermaid.md +3 -4
- package/dist/commands/flow-init.md +3 -4
- package/dist/commands/goal-development.md +32 -0
- package/dist/commands/goal-research.md +33 -0
- package/dist/commands/html-renderer.md +3 -4
- package/dist/commands/migration.md +3 -4
- package/dist/commands/performance.md +3 -4
- package/dist/commands/research-brainstorm.md +33 -0
- package/dist/commands/research-converge.md +33 -0
- package/dist/commands/research-design.md +33 -0
- package/dist/commands/research-finalize.md +33 -0
- package/dist/commands/research-fork.md +40 -0
- package/dist/commands/research-gather.md +33 -0
- package/dist/commands/research-plan.md +37 -0
- package/dist/commands/research-quick.md +37 -0
- package/dist/commands/research-synthesize.md +33 -0
- package/dist/commands/research.md +55 -37
- package/dist/commands/reviews-code.md +4 -4
- package/dist/commands/reviews-pragmatic.md +4 -4
- package/dist/commands/reviews-production-readiness.md +4 -4
- package/dist/commands/reviews-reality-check.md +4 -4
- package/dist/commands/reviews-spec-audit.md +4 -4
- package/dist/commands/rule-reviewer.md +38 -0
- package/dist/commands/standards-discover.md +3 -4
- package/dist/commands/standards-update.md +3 -4
- package/dist/commands/work.md +21 -21
- package/dist/configuration/skills-config.js +1 -1
- package/dist/index.js +5 -2
- package/dist/skills/agents-md-generator/SKILL.md +223 -0
- package/dist/skills/codebase-analyzer/SKILL.md +1 -1
- package/dist/skills/dev-analyze/SKILL.md +115 -0
- package/dist/skills/dev-bugfix/SKILL.md +452 -0
- package/dist/skills/dev-finalize/SKILL.md +118 -0
- package/dist/skills/dev-implement/SKILL.md +167 -0
- package/dist/skills/dev-plan/SKILL.md +147 -0
- package/dist/skills/dev-spec/SKILL.md +182 -0
- package/dist/skills/dev-tdd-red/SKILL.md +94 -0
- package/dist/skills/dev-verify/SKILL.md +160 -0
- package/dist/skills/development/SKILL.md +130 -522
- package/dist/skills/diagrams-mermaid/SKILL.md +3 -1
- package/dist/skills/docs-manager/SKILL.md +4 -4
- package/dist/skills/docs-manager/references/agents-md-template.md +1 -1
- package/dist/skills/flow-init/SKILL.md +34 -13
- package/dist/skills/goal-development/SKILL.md +96 -0
- package/dist/skills/goal-research/SKILL.md +118 -0
- package/dist/skills/html-renderer/SKILL.md +14 -1
- package/dist/skills/implementation-plan-executor/SKILL.md +1 -1
- package/dist/skills/implementation-verifier/SKILL.md +1 -1
- package/dist/skills/migration/SKILL.md +63 -18
- package/dist/skills/orchestrator-framework/SKILL.md +1 -1
- package/dist/skills/orchestrator-framework/references/command-namespacing.md +7 -0
- package/dist/skills/orchestrator-framework/references/confirm-or-revise-exception.md +20 -0
- package/dist/skills/orchestrator-framework/references/delegation-rules.md +54 -0
- package/dist/skills/orchestrator-framework/references/dispatcher-handoff.md +27 -0
- package/dist/skills/orchestrator-framework/references/gate-contract.md +112 -0
- package/dist/skills/orchestrator-framework/references/orchestrator-creation-checklist.md +3 -0
- package/dist/skills/orchestrator-framework/references/orchestrator-patterns.md +8 -50
- package/dist/skills/performance/SKILL.md +52 -18
- package/dist/skills/research/SKILL.md +249 -462
- package/dist/skills/research-brainstorm/SKILL.md +120 -0
- package/dist/skills/{research → research-brainstorm}/references/brainstorming-techniques.md +1 -1
- package/dist/skills/research-converge/SKILL.md +130 -0
- package/dist/skills/research-design/SKILL.md +146 -0
- package/dist/skills/{research → research-design}/references/design-techniques.md +1 -1
- package/dist/skills/research-finalize/SKILL.md +125 -0
- package/dist/skills/research-fork/SKILL.md +190 -0
- package/dist/skills/research-gather/SKILL.md +133 -0
- package/dist/skills/research-plan/SKILL.md +141 -0
- package/dist/skills/research-quick/SKILL.md +139 -0
- package/dist/skills/research-synthesize/SKILL.md +127 -0
- package/dist/skills/rule-reviewer/SKILL.md +334 -0
- package/dist/skills/standards-discover/SKILL.md +37 -14
- package/dist/skills/standards-update/SKILL.md +58 -10
- package/dist/templates/orchestrator-state-development.yml +14 -13
- package/dist/templates/orchestrator-state-research.yml +19 -13
- package/dist/tools/fork_task.js +36 -0
- package/dist/tools/verify_template.js +10 -31
- package/dist/utils/file-util.js +14 -8
- package/dist/utils/fork-task.js +74 -0
- package/dist/utils/plugin-info.js +20 -0
- package/dist/utils/yaml-structure.js +32 -0
- package/package.json +1 -1
- package/dist/commands/quick-bugfix.md +0 -37
- package/dist/commands/quick-dev.md +0 -182
- package/dist/commands/quick-plan.md +0 -167
- package/dist/constants.js +0 -4
- package/dist/skills/quick-bugfix/SKILL.md +0 -311
- package/dist/templates/quick-bugfix-task.yml +0 -10
- package/dist/templates/quick-dev-task.yml +0 -10
- package/dist/templates/quick-plan-task.yml +0 -11
- /package/dist/skills/{research → research-plan}/references/research-methodologies.md +0 -0
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
orchestrator:
|
|
2
2
|
started_phase: null
|
|
3
|
+
entry_point: null
|
|
3
4
|
completed_phases: []
|
|
4
5
|
failed_phases: []
|
|
5
6
|
auto_fix_attempts:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
codebase-analysed: 0
|
|
8
|
+
gap-analysed: 0
|
|
9
|
+
tdd-red-proven: 0
|
|
10
|
+
spec-written: 0
|
|
11
|
+
spec-audited: 0
|
|
12
|
+
plan-created: 0
|
|
13
|
+
implementation-done: 0
|
|
14
|
+
tdd-green-proven: 0
|
|
15
|
+
options-chosen: 0
|
|
16
|
+
verification-done: 0
|
|
17
|
+
e2e-run: 0
|
|
18
|
+
docs-generated: 0
|
|
19
|
+
task-completed: 0
|
|
19
20
|
options:
|
|
20
21
|
spec_audit_enabled: true
|
|
21
22
|
skip_test_suite: true
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
orchestrator:
|
|
2
2
|
started_phase: null
|
|
3
|
+
entry_point: null
|
|
3
4
|
completed_phases: []
|
|
4
5
|
failed_phases: []
|
|
5
6
|
auto_fix_attempts:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
design_enabled: null
|
|
7
|
+
brief-written: 0
|
|
8
|
+
plan-created: 0
|
|
9
|
+
findings-gathered: 0
|
|
10
|
+
synthesis-complete: 0
|
|
11
|
+
alternatives-generated: 0
|
|
12
|
+
approaches-chosen: 0
|
|
13
|
+
design-generated: 0
|
|
14
|
+
research-completed: 0
|
|
15
15
|
created: "YYYY-MM-DDTHH:MM:SSZ"
|
|
16
16
|
updated: "YYYY-MM-DDTHH:MM:SSZ"
|
|
17
17
|
task_path: null
|
|
@@ -38,17 +38,22 @@ research_context:
|
|
|
38
38
|
categories: []
|
|
39
39
|
count: 0
|
|
40
40
|
source: "planner | default"
|
|
41
|
+
project_doc_paths: []
|
|
41
42
|
phase_summaries:
|
|
42
|
-
|
|
43
|
+
plan:
|
|
43
44
|
summary: null
|
|
44
45
|
steps_completed: []
|
|
45
|
-
|
|
46
|
+
gather:
|
|
46
47
|
summary: null
|
|
47
|
-
|
|
48
|
+
synthesize:
|
|
49
|
+
summary: null
|
|
50
|
+
brainstorm:
|
|
51
|
+
summary: null
|
|
52
|
+
converge:
|
|
48
53
|
summary: null
|
|
49
54
|
decision_areas: []
|
|
50
55
|
deferred_ideas: []
|
|
51
|
-
|
|
56
|
+
design:
|
|
52
57
|
summary: null
|
|
53
58
|
architecture_style: null
|
|
54
59
|
decisions_count: 0
|
|
@@ -59,3 +64,4 @@ research_outputs:
|
|
|
59
64
|
solution_exploration: null
|
|
60
65
|
high_level_design: null
|
|
61
66
|
decision_log: null
|
|
67
|
+
synthesis: null
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { forkTask } from "../utils/fork-task.js";
|
|
4
|
+
export const fork_task = tool({
|
|
5
|
+
description: "Fork a research task: copy the whole source task directory into a new date-prefixed directory named from the slug, then trim the copied state so the fork continues from the chosen completed step (fork point) onwards. The source task is never modified.",
|
|
6
|
+
args: {
|
|
7
|
+
taskRoot: tool.schema.string().describe("Project-relative root of all tasks (typically '.owflow/tasks')"),
|
|
8
|
+
source: tool.schema.string().describe("Source task path or identifier under .owflow/tasks/research/"),
|
|
9
|
+
slug: tool.schema.string().describe("Lowercase-kebab-case slug for the fork name, 3-5 words, WITHOUT the date prefix (derived by the agent from a short descriptive name)"),
|
|
10
|
+
from: tool.schema.string().describe("Fork point: a completed step slug from the source task's completed_phases (e.g. 'synthesis-complete'); the fork continues from the step after it"),
|
|
11
|
+
intent: tool.schema.string().optional().describe("Optional one-line description of what the fork should explore; stamped into the fork's orchestrator.options.fork_information.intent"),
|
|
12
|
+
},
|
|
13
|
+
async execute(args, context) {
|
|
14
|
+
try {
|
|
15
|
+
const result = forkTask({
|
|
16
|
+
taskRoot: args.taskRoot,
|
|
17
|
+
source: args.source,
|
|
18
|
+
slug: args.slug,
|
|
19
|
+
from: args.from,
|
|
20
|
+
intent: args.intent,
|
|
21
|
+
cwd: context.directory,
|
|
22
|
+
});
|
|
23
|
+
return {
|
|
24
|
+
output: [
|
|
25
|
+
`FORK CREATED`,
|
|
26
|
+
`Fork path: ${path.relative(context.directory, result.forkPath).split(path.sep).join("/")}`,
|
|
27
|
+
`Fork point: ${result.forkPoint}`,
|
|
28
|
+
...(args.intent ? [`Intent: ${args.intent}`] : []),
|
|
29
|
+
].join("\n"),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return { output: error.message };
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { tool } from "@opencode-ai/plugin";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import yaml from "yaml";
|
|
5
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { findStructuralErrors, parseYamlFile, } from "../utils/yaml-structure.js";
|
|
6
6
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
7
|
export const verify_template = tool({
|
|
8
8
|
description: "Check if file in the given path exists and follows correct YAML structure by checking against the template file from /templates.",
|
|
@@ -20,39 +20,18 @@ export const verify_template = tool({
|
|
|
20
20
|
return { output: `Template '${templateName}' not found. Hint: Verify the template name is correct and exists in the /templates folder (e.g., 'orchestrator-state-development.yml').` };
|
|
21
21
|
}
|
|
22
22
|
let targetYaml;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
catch (error) {
|
|
28
|
-
return { output: `YAML Syntax Error in ${filePath}: ${error.message}. Hint: Check the file content for invalid YAML formatting, such as incorrect indentation or unescaped strings, and fix them.` };
|
|
23
|
+
const parsedTarget = parseYamlFile(absolutePath);
|
|
24
|
+
if (!parsedTarget.ok) {
|
|
25
|
+
return { output: `YAML Syntax Error in ${filePath}: ${parsedTarget.error}. Hint: Check the file content for invalid YAML formatting, such as incorrect indentation or unescaped strings, and fix them.` };
|
|
29
26
|
}
|
|
27
|
+
targetYaml = parsedTarget.data;
|
|
30
28
|
let templateYaml;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
return { output: `Internal Error: Failed to parse reference template YAML '${templateName}': ${error.message}. Hint: The template file itself contains invalid YAML syntax.` };
|
|
37
|
-
}
|
|
38
|
-
function checkStructure(templateObj, targetObj, currentPath = "") {
|
|
39
|
-
let errors = [];
|
|
40
|
-
if (typeof templateObj !== 'object' || templateObj === null) {
|
|
41
|
-
return errors;
|
|
42
|
-
}
|
|
43
|
-
for (const key of Object.keys(templateObj)) {
|
|
44
|
-
const newPath = currentPath ? `${currentPath}.${key}` : key;
|
|
45
|
-
if (typeof targetObj !== 'object' || targetObj === null || !(key in targetObj)) {
|
|
46
|
-
errors.push(`Missing key: ${newPath}`);
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
if (typeof templateObj[key] === 'object' && templateObj[key] !== null && !Array.isArray(templateObj[key])) {
|
|
50
|
-
errors.push(...checkStructure(templateObj[key], targetObj[key], newPath));
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return errors;
|
|
29
|
+
const parsedTemplate = parseYamlFile(templatePath);
|
|
30
|
+
if (!parsedTemplate.ok) {
|
|
31
|
+
return { output: `Internal Error: Failed to parse reference template YAML '${templateName}': ${parsedTemplate.error}. Hint: The template file itself contains invalid YAML syntax.` };
|
|
54
32
|
}
|
|
55
|
-
|
|
33
|
+
templateYaml = parsedTemplate.data;
|
|
34
|
+
const errors = findStructuralErrors(templateYaml, targetYaml);
|
|
56
35
|
if (errors.length > 0) {
|
|
57
36
|
return { output: `YAML Structure Validation Failed. Your file is missing the following required keys:\n- ${errors.join("\n- ")}\n\nHint: Update the file at ${filePath} to include these missing keys so it matches the structure of '${templateName}'.` };
|
|
58
37
|
}
|
package/dist/utils/file-util.js
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import matter from "gray-matter";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { PLUGIN_ROOT } from "
|
|
4
|
+
import { PLUGIN_ROOT } from "./plugin-info.js";
|
|
5
5
|
export const loadMarkdownDir = (dirPath) => {
|
|
6
6
|
const fullPath = path.join(PLUGIN_ROOT, dirPath);
|
|
7
|
+
let files;
|
|
7
8
|
try {
|
|
8
|
-
|
|
9
|
-
.readdirSync(fullPath)
|
|
10
|
-
.filter((f) => f.endsWith(".md"))
|
|
11
|
-
.map((f) => {
|
|
12
|
-
const raw = fs.readFileSync(path.join(fullPath, f), "utf8");
|
|
13
|
-
return matter(raw);
|
|
14
|
-
});
|
|
9
|
+
files = fs.readdirSync(fullPath).filter((f) => f.endsWith(".md"));
|
|
15
10
|
}
|
|
16
11
|
catch {
|
|
17
12
|
return [];
|
|
18
13
|
}
|
|
14
|
+
const parsed = [];
|
|
15
|
+
for (const f of files) {
|
|
16
|
+
try {
|
|
17
|
+
const raw = fs.readFileSync(path.join(fullPath, f), "utf8");
|
|
18
|
+
parsed.push(matter(raw));
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
console.warn(`[owflow] Skipping unparseable markdown file ${f} in ${dirPath}:`, e instanceof Error ? e.message : e);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return parsed;
|
|
19
25
|
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import yaml from "yaml";
|
|
4
|
+
import { parseYamlFile } from "./yaml-structure.js";
|
|
5
|
+
/** Lowercase kebab-case, exactly 3-5 words of [a-z0-9] (Task Name Generation convention). */
|
|
6
|
+
export const RESEARCH_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+){2,4}$/;
|
|
7
|
+
const FORK_TERMINAL_STEP = "research-completed";
|
|
8
|
+
/**
|
|
9
|
+
* Copies the whole source task directory into a new date-prefixed directory
|
|
10
|
+
* named from the slug, then trims the copied state so the fork continues
|
|
11
|
+
* from the fork point onwards. The source task is never modified.
|
|
12
|
+
*/
|
|
13
|
+
export const forkTask = (input) => {
|
|
14
|
+
const cwd = input.cwd ?? process.cwd();
|
|
15
|
+
if (!input.slug || !RESEARCH_SLUG_PATTERN.test(input.slug)) {
|
|
16
|
+
throw new Error("INVALID_NAME: slug must be lowercase kebab-case, 3-5 words of [a-z0-9] (e.g. 'compare-caching-strategies')");
|
|
17
|
+
}
|
|
18
|
+
const taskRoot = path.resolve(cwd, input.taskRoot);
|
|
19
|
+
const researchRoot = path.join(taskRoot, "research");
|
|
20
|
+
const sourceDir = [
|
|
21
|
+
path.resolve(cwd, input.source),
|
|
22
|
+
path.resolve(researchRoot, input.source),
|
|
23
|
+
].find((candidate) => fs.existsSync(candidate) && fs.statSync(candidate).isDirectory());
|
|
24
|
+
if (sourceDir === undefined) {
|
|
25
|
+
throw new Error(`INVALID_SOURCE: no task directory at ${input.source}. Hint: pass the task path or a directory name under .owflow/tasks/research/.`);
|
|
26
|
+
}
|
|
27
|
+
if (!sourceDir.startsWith(researchRoot + path.sep)) {
|
|
28
|
+
throw new Error(`INVALID_SOURCE: ${input.source} is not a research task directory under .owflow/tasks/research/.`);
|
|
29
|
+
}
|
|
30
|
+
const parsedSourceState = parseYamlFile(path.join(sourceDir, "orchestrator-state.yml"));
|
|
31
|
+
if (!parsedSourceState.ok || !parsedSourceState.data) {
|
|
32
|
+
throw new Error(`INVALID_SOURCE: ${parsedSourceState.error ?? `no orchestrator-state.yml in ${input.source}`}`);
|
|
33
|
+
}
|
|
34
|
+
const sourceState = parsedSourceState.data;
|
|
35
|
+
const completed = Array.isArray(sourceState?.orchestrator?.completed_phases)
|
|
36
|
+
? sourceState.orchestrator.completed_phases.filter((s) => typeof s === "string")
|
|
37
|
+
: [];
|
|
38
|
+
if (input.from === FORK_TERMINAL_STEP) {
|
|
39
|
+
throw new Error(`UNKNOWN_STEP: ${FORK_TERMINAL_STEP} is not a valid fork point — nothing diverges after completion.`);
|
|
40
|
+
}
|
|
41
|
+
if (!completed.includes(input.from)) {
|
|
42
|
+
throw new Error(`UNKNOWN_STEP: ${input.from} is not completed in the source task. Completed steps: ${completed.join(", ") || "none"}`);
|
|
43
|
+
}
|
|
44
|
+
const forkName = `${new Date().toISOString().slice(0, 10)}-${input.slug}`;
|
|
45
|
+
const forkPath = path.join(researchRoot, forkName);
|
|
46
|
+
if (fs.existsSync(forkPath)) {
|
|
47
|
+
throw new Error(`NAME_TAKEN: a research task directory "${forkName}" already exists. Hint: ask the user for another short descriptive name (3-5 words).`);
|
|
48
|
+
}
|
|
49
|
+
fs.cpSync(sourceDir, forkPath, { recursive: true });
|
|
50
|
+
const forkState = structuredClone(sourceState);
|
|
51
|
+
forkState.orchestrator.started_phase = null;
|
|
52
|
+
forkState.orchestrator.completed_phases = completed.slice(0, completed.indexOf(input.from) + 1);
|
|
53
|
+
forkState.orchestrator.entry_point = "research-fork";
|
|
54
|
+
forkState.orchestrator.task_path = path
|
|
55
|
+
.relative(cwd, forkPath)
|
|
56
|
+
.split(path.sep)
|
|
57
|
+
.join("/");
|
|
58
|
+
forkState.orchestrator.options = {
|
|
59
|
+
...(forkState.orchestrator.options ?? {}),
|
|
60
|
+
fork_information: {
|
|
61
|
+
forked_from: path.basename(sourceDir),
|
|
62
|
+
fork_point: input.from,
|
|
63
|
+
forked_at: new Date().toISOString(),
|
|
64
|
+
...(input.intent ? { intent: input.intent } : {}),
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
forkState.task = {
|
|
68
|
+
...forkState.task,
|
|
69
|
+
status: "in_progress",
|
|
70
|
+
title: `${forkState.task?.title ?? "Research task"} (fork of ${path.basename(sourceDir)})`,
|
|
71
|
+
};
|
|
72
|
+
fs.writeFileSync(path.join(forkPath, "orchestrator-state.yml"), yaml.stringify(forkState), "utf8");
|
|
73
|
+
return { forkPath, forkName, forkPoint: input.from };
|
|
74
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
export const PLUGIN_ROOT = path.join(__dirname, ".."); // Points to dist/ where skills/commands/agents are copied
|
|
6
|
+
const UNKNOWN_VERSION = "unknown";
|
|
7
|
+
export const readPluginVersion = (pluginRoot = PLUGIN_ROOT) => {
|
|
8
|
+
try {
|
|
9
|
+
const packageJsonPath = path.join(pluginRoot, "..", "package.json");
|
|
10
|
+
const raw = fs.readFileSync(packageJsonPath, "utf8");
|
|
11
|
+
const version = JSON.parse(raw).version;
|
|
12
|
+
return typeof version === "string" && version.length > 0
|
|
13
|
+
? version
|
|
14
|
+
: UNKNOWN_VERSION;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return UNKNOWN_VERSION;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
export const PLUGIN_VERSION = readPluginVersion();
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import yaml from "yaml";
|
|
3
|
+
export const parseYamlFile = (absolutePath) => {
|
|
4
|
+
try {
|
|
5
|
+
const fileContent = fs.readFileSync(absolutePath, "utf8");
|
|
6
|
+
return { ok: true, data: yaml.parse(fileContent) };
|
|
7
|
+
}
|
|
8
|
+
catch (error) {
|
|
9
|
+
return { ok: false, error: error.message };
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export const findStructuralErrors = (templateObj, targetObj, currentPath = "") => {
|
|
13
|
+
const errors = [];
|
|
14
|
+
if (typeof templateObj !== "object" || templateObj === null) {
|
|
15
|
+
return errors;
|
|
16
|
+
}
|
|
17
|
+
for (const key of Object.keys(templateObj)) {
|
|
18
|
+
const newPath = currentPath ? `${currentPath}.${key}` : key;
|
|
19
|
+
if (typeof targetObj !== "object" ||
|
|
20
|
+
targetObj === null ||
|
|
21
|
+
!(key in targetObj)) {
|
|
22
|
+
errors.push(`Missing key: ${newPath}`);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (typeof templateObj[key] === "object" &&
|
|
26
|
+
templateObj[key] !== null &&
|
|
27
|
+
!Array.isArray(templateObj[key])) {
|
|
28
|
+
errors.push(...findStructuralErrors(templateObj[key], targetObj[key], newPath));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return errors;
|
|
32
|
+
};
|
package/package.json
CHANGED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: quick-bugfix
|
|
3
|
-
description: Quick bug fix with TDD red/green gates and complexity escalation
|
|
4
|
-
argument-hint: "[bug description]"
|
|
5
|
-
generated-from-skill: true
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
CRITICAL INSTRUCTION: You MUST invoke the quick-bugfix skill immediately as your FIRST action.
|
|
9
|
-
|
|
10
|
-
Use the Skill tool with these exact parameters:
|
|
11
|
-
name: "quick-bugfix"
|
|
12
|
-
prompt: "$ARGUMENTS"
|
|
13
|
-
|
|
14
|
-
DO NOT:
|
|
15
|
-
|
|
16
|
-
- Analyze the task before invoking the skill
|
|
17
|
-
- Decide the task is "straightforward" and skip the skill
|
|
18
|
-
- Substitute your own approach or workflow
|
|
19
|
-
- Execute any part of the workflow yourself
|
|
20
|
-
|
|
21
|
-
WHY: The user explicitly chose this workflow by using /quick-bugfix.
|
|
22
|
-
Invoke the skill now and let it orchestrate the complete workflow.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## About This Workflow
|
|
27
|
-
|
|
28
|
-
Quick bug fix with TDD red/green gates and complexity escalation
|
|
29
|
-
|
|
30
|
-
The skill handles:
|
|
31
|
-
|
|
32
|
-
- Task directory creation and state management
|
|
33
|
-
- Phase execution with interactive gates
|
|
34
|
-
- Subagent delegation for specialized work
|
|
35
|
-
- Pause/resume capability
|
|
36
|
-
|
|
37
|
-
See `skills/quick-bugfix/SKILL.md` for complete workflow documentation.
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: quick-dev
|
|
3
|
-
description: Implement task directly with AI SDLC standards awareness (no planning mode)
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Quick Development with Standards Awareness
|
|
7
|
-
|
|
8
|
-
Implement a task directly without entering planning mode, while still applying project standards from `.owflow/docs/`.
|
|
9
|
-
|
|
10
|
-
## Usage
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
/quick-dev [task description]
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## Examples
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
/quick-dev "Add a logout button to the navbar"
|
|
20
|
-
/quick-dev "Fix the typo in the error message"
|
|
21
|
-
/quick-dev "Update the API endpoint to accept JSON"
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## When to Use
|
|
27
|
-
|
|
28
|
-
**Use `/quick-dev` when:**
|
|
29
|
-
|
|
30
|
-
- Task is clear and well-defined
|
|
31
|
-
- You know what needs to be done
|
|
32
|
-
- No architectural decisions needed
|
|
33
|
-
- Quick fixes, small features, or straightforward changes
|
|
34
|
-
|
|
35
|
-
**Use `/quick-plan` instead when:**
|
|
36
|
-
|
|
37
|
-
- Task scope is uncertain
|
|
38
|
-
- Multiple implementation approaches possible
|
|
39
|
-
- Architectural decisions required
|
|
40
|
-
- You want user approval before coding
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Workflow
|
|
45
|
-
|
|
46
|
-
### Step 1: Parse Input
|
|
47
|
-
|
|
48
|
-
**Get the task description:**
|
|
49
|
-
|
|
50
|
-
- If provided as argument, use it directly
|
|
51
|
-
- If not provided, use question to prompt:
|
|
52
|
-
```
|
|
53
|
-
"What would you like to implement? Please describe the task."
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### Step 1b: Create Task Directory
|
|
57
|
-
|
|
58
|
-
**Create a lightweight task directory for artifact anchoring.**
|
|
59
|
-
|
|
60
|
-
1. Generate a task name from the task description:
|
|
61
|
-
- Extract 3–5 key words, convert to lowercase kebab-case
|
|
62
|
-
- Prepend today's date: `YYYY-MM-DD-kebab-name`
|
|
63
|
-
- Examples: "Add a logout button to the navbar" → `2026-05-28-add-navbar-logout-button`, "Update the API endpoint to accept JSON" → `2026-05-28-update-api-accept-json`
|
|
64
|
-
2. Create directory: `.owflow/tasks/quick-dev/YYYY-MM-DD-task-name/`
|
|
65
|
-
3. Write `task.yml` with initial state using the template [src/templates/quick-dev-task.yml](../templates/quick-dev-task.yml).
|
|
66
|
-
4. **CRITICAL**: Use the `verify_template` tool immediately after creation to check YAML validity against `quick-dev-task.yml`.
|
|
67
|
-
|
|
68
|
-
### Step 2: Discover Standards
|
|
69
|
-
|
|
70
|
-
**Check if `.owflow/docs/INDEX.md` exists:**
|
|
71
|
-
|
|
72
|
-
**If exists:**
|
|
73
|
-
|
|
74
|
-
1. Read INDEX.md to discover available documentation and standards
|
|
75
|
-
2. Identify which standards are relevant based on:
|
|
76
|
-
- The categories and files listed in INDEX.md
|
|
77
|
-
- The nature of the task
|
|
78
|
-
- Keywords in the task description
|
|
79
|
-
3. **READ the applicable standard files** (see Standards Reading Enforcement below)
|
|
80
|
-
4. **Update `task.yml`**: Add paths of standards read to `standards_applied` list
|
|
81
|
-
|
|
82
|
-
**If not exists:**
|
|
83
|
-
|
|
84
|
-
- Note that no standards are available
|
|
85
|
-
- Suggest running `/flow-init` in completion message
|
|
86
|
-
|
|
87
|
-
### Standards Reading Enforcement (MANDATORY)
|
|
88
|
-
|
|
89
|
-
**BLOCKING**: Reading INDEX.md alone is NOT sufficient. You MUST read actual standard files.
|
|
90
|
-
|
|
91
|
-
**Enforcement Process**:
|
|
92
|
-
|
|
93
|
-
1. Read INDEX.md to discover available standards
|
|
94
|
-
2. Identify which standards apply based on task description
|
|
95
|
-
3. **READ each applicable standard file** using Read tool (not just note it exists)
|
|
96
|
-
4. Apply standards during implementation
|
|
97
|
-
5. List applied standards in completion summary
|
|
98
|
-
|
|
99
|
-
**Examples of standard discovery**:
|
|
100
|
-
|
|
101
|
-
- Task mentions "upload" → Read file-handling standards
|
|
102
|
-
- Task mentions "form" → Read validation and accessibility standards
|
|
103
|
-
- Task mentions "API" → Read api and error-handling standards
|
|
104
|
-
|
|
105
|
-
### Step 3: Implement with Standards
|
|
106
|
-
|
|
107
|
-
**MANDATORY**: During implementation:
|
|
108
|
-
|
|
109
|
-
1. Explore the codebase to understand context (using Glob, Grep, Read)
|
|
110
|
-
2. **Apply discovered standards** - Reference the standard files you read
|
|
111
|
-
3. For each code change, verify it follows applicable standards
|
|
112
|
-
4. If you encounter new areas while coding (e.g., auth, database), read applicable standards before proceeding
|
|
113
|
-
5. Make the necessary code changes
|
|
114
|
-
6. Run relevant tests if applicable
|
|
115
|
-
|
|
116
|
-
### Step 4: Verify Standards Compliance
|
|
117
|
-
|
|
118
|
-
**After implementation, verify:**
|
|
119
|
-
|
|
120
|
-
1. Review changes against applicable standards
|
|
121
|
-
2. Confirm key guidelines were followed
|
|
122
|
-
3. Note any standards that were applied
|
|
123
|
-
|
|
124
|
-
### Step 5: Summary
|
|
125
|
-
|
|
126
|
-
**Write `summary.md`** in the task directory:
|
|
127
|
-
|
|
128
|
-
```markdown
|
|
129
|
-
# Task Summary
|
|
130
|
-
|
|
131
|
-
**Command**: quick-dev
|
|
132
|
-
**Date**: YYYY-MM-DD
|
|
133
|
-
**Status**: completed
|
|
134
|
-
|
|
135
|
-
## What Was Done
|
|
136
|
-
[What was implemented]
|
|
137
|
-
|
|
138
|
-
## Files Modified
|
|
139
|
-
- `path/to/file`
|
|
140
|
-
|
|
141
|
-
## Standards Applied
|
|
142
|
-
- [standard]: [guideline]
|
|
143
|
-
|
|
144
|
-
## Tests
|
|
145
|
-
- [test file] — [result]
|
|
146
|
-
|
|
147
|
-
## Commit Suggestion
|
|
148
|
-
[conventional commit message]
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
**Update `task.yml`**: set `status: completed`, `updated: [now]`.
|
|
152
|
-
|
|
153
|
-
**Provide completion summary to user:**
|
|
154
|
-
|
|
155
|
-
- What was implemented
|
|
156
|
-
- Which standards from INDEX.md were applied
|
|
157
|
-
- Any tests run and their results
|
|
158
|
-
- Suggestions for follow-up (if any)
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
## What This Does
|
|
163
|
-
|
|
164
|
-
1. **Parses** task description from user input
|
|
165
|
-
2. **Creates** lightweight task directory with `task.yml` for artifact anchoring
|
|
166
|
-
3. **Discovers** applicable standards from `.owflow/docs/INDEX.md`
|
|
167
|
-
4. **READS** actual standard files (MANDATORY - not just INDEX.md)
|
|
168
|
-
5. **Implements** directly without planning mode approval
|
|
169
|
-
6. **Verifies** standards were followed
|
|
170
|
-
7. **Writes** `summary.md` in task directory and updates `task.yml` to `completed`
|
|
171
|
-
8. **Summarizes** what was done and which standards were read and applied
|
|
172
|
-
|
|
173
|
-
## Graceful Fallback
|
|
174
|
-
|
|
175
|
-
**If `.owflow/docs/` does not exist:**
|
|
176
|
-
|
|
177
|
-
Proceed with implementation normally, then note:
|
|
178
|
-
|
|
179
|
-
```
|
|
180
|
-
"No AI SDLC standards found. Consider running `/flow-init` to initialize
|
|
181
|
-
project documentation and coding standards for better consistency."
|
|
182
|
-
```
|