@techierathore/techieflow 1.0.0
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/.claude/commands/TechieFlow/agents/analyst.md +97 -0
- package/.claude/commands/TechieFlow/agents/architect.md +84 -0
- package/.claude/commands/TechieFlow/agents/flow-master.md +217 -0
- package/.claude/commands/TechieFlow/agents/verifier.md +72 -0
- package/.claude/commands/TechieFlow/tasks/_metrics-emit-gate.md +138 -0
- package/.claude/commands/TechieFlow/tasks/_smoke-test-policy.md +98 -0
- package/.claude/commands/TechieFlow/tasks/_status-update-gate.md +78 -0
- package/.claude/commands/TechieFlow/tasks/_yolo-mode.md +77 -0
- package/.claude/commands/TechieFlow/tasks/advanced-elicitation.md +117 -0
- package/.claude/commands/TechieFlow/tasks/amend-docs.md +149 -0
- package/.claude/commands/TechieFlow/tasks/author-brd.md +79 -0
- package/.claude/commands/TechieFlow/tasks/build-phase.md +231 -0
- package/.claude/commands/TechieFlow/tasks/create-deep-research-prompt.md +278 -0
- package/.claude/commands/TechieFlow/tasks/create-doc.md +101 -0
- package/.claude/commands/TechieFlow/tasks/day1-brownfield.md +507 -0
- package/.claude/commands/TechieFlow/tasks/day1-greenfield.md +224 -0
- package/.claude/commands/TechieFlow/tasks/devguide.md +224 -0
- package/.claude/commands/TechieFlow/tasks/document-project.md +343 -0
- package/.claude/commands/TechieFlow/tasks/execute-checklist.md +86 -0
- package/.claude/commands/TechieFlow/tasks/facilitate-brainstorming-session.md +136 -0
- package/.claude/commands/TechieFlow/tasks/fix-issues.md +134 -0
- package/.claude/commands/TechieFlow/tasks/generate-html.md +115 -0
- package/.claude/commands/TechieFlow/tasks/handoff-phase.md +126 -0
- package/.claude/commands/TechieFlow/tasks/index-docs.md +173 -0
- package/.claude/commands/TechieFlow/tasks/kb-mode-interaction.md +75 -0
- package/.claude/commands/TechieFlow/tasks/log-miss.md +160 -0
- package/.claude/commands/TechieFlow/tasks/metrics-report.md +143 -0
- package/.claude/commands/TechieFlow/tasks/mockups.md +122 -0
- package/.claude/commands/TechieFlow/tasks/productguide.md +105 -0
- package/.claude/commands/TechieFlow/tasks/refresh-status.md +135 -0
- package/.claude/commands/TechieFlow/tasks/render-workflow-docs.md +117 -0
- package/.claude/commands/TechieFlow/tasks/shard-doc.md +185 -0
- package/.claude/commands/TechieFlow/tasks/split-brd.md +131 -0
- package/.claude/commands/TechieFlow/tasks/triage-issues.md +157 -0
- package/.claude/commands/TechieFlow/tasks/verify-phase.md +579 -0
- package/.claude/commands/generate-html.md +124 -0
- package/.codex/config.toml +46 -0
- package/.codex/hooks.json +63 -0
- package/.codex/rules/techieflow.rules +8 -0
- package/.opencode/command/generate-html.md +129 -0
- package/.opencode/plugin/techieflow.js +350 -0
- package/.tfcore/TOKEN-GUIDE.md +59 -0
- package/.tfcore/agents/analyst.md +97 -0
- package/.tfcore/agents/architect.md +84 -0
- package/.tfcore/agents/flow-master.md +217 -0
- package/.tfcore/agents/verifier.md +72 -0
- package/.tfcore/checklists/architect-checklist.md +438 -0
- package/.tfcore/core-config.yaml +47 -0
- package/.tfcore/data/brainstorming-techniques.md +36 -0
- package/.tfcore/data/elicitation-methods.md +154 -0
- package/.tfcore/data/techieflow-kb.md +807 -0
- package/.tfcore/data/technical-preferences.md +3 -0
- package/.tfcore/enhanced-ide-development-workflow.md +248 -0
- package/.tfcore/hooks/block-git.sh +301 -0
- package/.tfcore/hooks/codex-adapter.py +248 -0
- package/.tfcore/hooks/guard-artifacts.sh +101 -0
- package/.tfcore/hooks/guard-status-html.sh +102 -0
- package/.tfcore/hooks/guard-status.sh +124 -0
- package/.tfcore/hooks/guard-verify.sh +108 -0
- package/.tfcore/hooks/metrics-session.sh +129 -0
- package/.tfcore/hooks/session-pointer.sh +52 -0
- package/.tfcore/hooks/sweep-artifacts.sh +198 -0
- package/.tfcore/install-manifest.yaml +231 -0
- package/.tfcore/routing.yaml +105 -0
- package/.tfcore/tasks/_metrics-emit-gate.md +138 -0
- package/.tfcore/tasks/_smoke-test-policy.md +98 -0
- package/.tfcore/tasks/_status-update-gate.md +78 -0
- package/.tfcore/tasks/_yolo-mode.md +77 -0
- package/.tfcore/tasks/advanced-elicitation.md +117 -0
- package/.tfcore/tasks/amend-docs.md +149 -0
- package/.tfcore/tasks/author-brd.md +79 -0
- package/.tfcore/tasks/build-phase.md +231 -0
- package/.tfcore/tasks/create-deep-research-prompt.md +278 -0
- package/.tfcore/tasks/create-doc.md +101 -0
- package/.tfcore/tasks/day1-brownfield.md +507 -0
- package/.tfcore/tasks/day1-greenfield.md +224 -0
- package/.tfcore/tasks/devguide.md +224 -0
- package/.tfcore/tasks/document-project.md +343 -0
- package/.tfcore/tasks/execute-checklist.md +86 -0
- package/.tfcore/tasks/facilitate-brainstorming-session.md +136 -0
- package/.tfcore/tasks/fix-issues.md +134 -0
- package/.tfcore/tasks/generate-html.md +115 -0
- package/.tfcore/tasks/handoff-phase.md +126 -0
- package/.tfcore/tasks/index-docs.md +173 -0
- package/.tfcore/tasks/kb-mode-interaction.md +75 -0
- package/.tfcore/tasks/log-miss.md +160 -0
- package/.tfcore/tasks/metrics-report.md +143 -0
- package/.tfcore/tasks/mockups.md +122 -0
- package/.tfcore/tasks/productguide.md +105 -0
- package/.tfcore/tasks/refresh-status.md +135 -0
- package/.tfcore/tasks/render-workflow-docs.md +117 -0
- package/.tfcore/tasks/shard-doc.md +185 -0
- package/.tfcore/tasks/split-brd.md +131 -0
- package/.tfcore/tasks/triage-issues.md +157 -0
- package/.tfcore/tasks/verify-phase.md +579 -0
- package/.tfcore/telemetry/SCHEMA.md +678 -0
- package/.tfcore/telemetry/install-metrics.sh +390 -0
- package/.tfcore/telemetry/pre-commit +94 -0
- package/.tfcore/telemetry/tf-metrics.sh +1415 -0
- package/.tfcore/templates/architecture-tmpl.yaml +650 -0
- package/.tfcore/templates/brainstorming-output-tmpl.yaml +156 -0
- package/.tfcore/templates/brownfield-architecture-tmpl.yaml +476 -0
- package/.tfcore/templates/competitor-analysis-tmpl.yaml +306 -0
- package/.tfcore/templates/front-end-architecture-tmpl.yaml +218 -0
- package/.tfcore/templates/fullstack-architecture-tmpl.yaml +823 -0
- package/.tfcore/templates/market-research-tmpl.yaml +252 -0
- package/.tfcore/templates/project-brief-tmpl.yaml +221 -0
- package/.tfcore/templates/v4custom/app-agents-md-tmpl.md +61 -0
- package/.tfcore/templates/v4custom/app-architecture-tmpl.md +127 -0
- package/.tfcore/templates/v4custom/app-brd-tmpl.md +204 -0
- package/.tfcore/templates/v4custom/app-checklist-tmpl.md +90 -0
- package/.tfcore/templates/v4custom/app-claude-md-tmpl.md +33 -0
- package/.tfcore/templates/v4custom/app-devguide-tmpl.md +167 -0
- package/.tfcore/templates/v4custom/app-editorconfig-tmpl.editorconfig +44 -0
- package/.tfcore/templates/v4custom/app-library-feedback-tmpl.md +31 -0
- package/.tfcore/templates/v4custom/app-productguide-tmpl.md +54 -0
- package/.tfcore/templates/v4custom/app-project-status-tmpl.md +98 -0
- package/.tfcore/templates/v4custom/app-uidesign-tmpl.md +48 -0
- package/.tfcore/templates/v4custom/app-usageguide-tmpl.md +67 -0
- package/.tfcore/templates/v4custom/build-invocation-ladder.md +190 -0
- package/.tfcore/templates/v4custom/html-render-shell.md +502 -0
- package/.tfcore/templates/v4custom/metrics-report-template.md +273 -0
- package/.tfcore/templates/v4custom/opencode-operating-contract.md +56 -0
- package/.tfcore/user-guide.md +633 -0
- package/.tfcore/utils/techieflow-doc-template.md +325 -0
- package/.tfcore/utils/tf-assets.sh +310 -0
- package/.tfcore/utils/tf-codex-bind.py +196 -0
- package/.tfcore/utils/tf-codex-telemetry.py +60 -0
- package/.tfcore/utils/tf-emit.sh +1075 -0
- package/.tfcore/utils/tf-gitignore-audit.sh +281 -0
- package/.tfcore/utils/tf-goal.sh +421 -0
- package/.tfcore/utils/tf-harness.sh +160 -0
- package/.tfcore/utils/tf-mockup-parity.mjs +555 -0
- package/.tfcore/utils/tf-mockup-parity.sh +65 -0
- package/.tfcore/utils/tf-opencode-audit.py +126 -0
- package/.tfcore/utils/tf-perf.sh +241 -0
- package/.tfcore/utils/tf-render-html.py +715 -0
- package/.tfcore/utils/tf-render-html.sh +28 -0
- package/.tfcore/utils/tf-routing-bind.sh +216 -0
- package/.tfcore/utils/tf-routing.sh +247 -0
- package/.tfcore/utils/tf-yolo.sh +119 -0
- package/.tfcore/working-in-the-brownfield.md +606 -0
- package/LICENSE +201 -0
- package/README.md +1212 -0
- package/WORKFLOW.html +1986 -0
- package/docs/TechieFlow-Installation.md +299 -0
- package/opencode.jsonc +929 -0
- package/package.json +60 -0
- package/scripts/install.mjs +992 -0
- package/scripts/test-install.mjs +505 -0
- package/scripts/validate.mjs +155 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// scripts/validate.mjs — the checks that run before every publish and on every push.
|
|
3
|
+
//
|
|
4
|
+
// 1. Mirror parity: every file under .claude/commands/TechieFlow/<sub>/ is byte-identical
|
|
5
|
+
// to .tfcore/<sub>/. Claude Code only reads the mirror, so drift means Claude Code and
|
|
6
|
+
// OpenCode run different instructions.
|
|
7
|
+
// 2. OpenCode references: every {file:...} in opencode.jsonc points at a file that exists.
|
|
8
|
+
// One dead reference makes OpenCode reject the whole config.
|
|
9
|
+
// 3. Shell syntax: `bash -n` on every .sh file in the repository.
|
|
10
|
+
// 4. Package contents: `npm pack --dry-run` succeeds, ships every file the shell scripts
|
|
11
|
+
// deploy, and ships none of the local-only or per-machine files.
|
|
12
|
+
//
|
|
13
|
+
// Exit code 0 means every check passed. Any failure exits 1 and names the problem.
|
|
14
|
+
|
|
15
|
+
import { spawnSync } from "node:child_process";
|
|
16
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
17
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
|
|
20
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
21
|
+
const problems = [];
|
|
22
|
+
let passed = 0;
|
|
23
|
+
|
|
24
|
+
function check(name, fn) {
|
|
25
|
+
try {
|
|
26
|
+
fn();
|
|
27
|
+
passed++;
|
|
28
|
+
console.log(`ok ${name}`);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
problems.push(`${name}: ${error.message}`);
|
|
31
|
+
console.log(`FAIL ${name}\n ${error.message.split("\n").join("\n ")}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function assert(condition, message) {
|
|
36
|
+
if (!condition) throw new Error(message);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const skipDirectories = new Set([".git", "node_modules"]);
|
|
40
|
+
|
|
41
|
+
function filesUnder(directory) {
|
|
42
|
+
const out = [];
|
|
43
|
+
const walk = (current) => {
|
|
44
|
+
for (const entry of readdirSync(current, { withFileTypes: true })) {
|
|
45
|
+
if (entry.isDirectory()) { if (!skipDirectories.has(entry.name)) walk(join(current, entry.name)); }
|
|
46
|
+
else if (entry.isFile()) out.push(join(current, entry.name));
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
if (existsSync(directory)) walk(directory);
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const rel = (path) => relative(root, path).split("\\").join("/");
|
|
54
|
+
|
|
55
|
+
// ---- 1. mirror parity
|
|
56
|
+
check("Claude mirror is byte-identical to .tfcore/", () => {
|
|
57
|
+
const mirror = join(root, ".claude", "commands", "TechieFlow");
|
|
58
|
+
const differences = [];
|
|
59
|
+
for (const sub of readdirSync(mirror)) {
|
|
60
|
+
const coreFiles = new Map(filesUnder(join(root, ".tfcore", sub)).map((f) => [relative(join(root, ".tfcore", sub), f), f]));
|
|
61
|
+
const mirrorFiles = new Map(filesUnder(join(mirror, sub)).map((f) => [relative(join(mirror, sub), f), f]));
|
|
62
|
+
for (const [name, corePath] of coreFiles) {
|
|
63
|
+
if (!mirrorFiles.has(name)) differences.push(`missing from mirror: ${sub}/${name}`);
|
|
64
|
+
else if (!readFileSync(corePath).equals(readFileSync(mirrorFiles.get(name)))) differences.push(`content differs: ${sub}/${name}`);
|
|
65
|
+
}
|
|
66
|
+
for (const name of mirrorFiles.keys()) if (!coreFiles.has(name)) differences.push(`only in mirror: ${sub}/${name}`);
|
|
67
|
+
}
|
|
68
|
+
assert(differences.length === 0, `${differences.length} difference(s) between .tfcore/ and .claude/commands/TechieFlow/:\n${differences.join("\n")}\nFix: copy the changed files from .tfcore/ over the mirror, or re-run the scaffold's agent sync for every folder.`);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// ---- 2. OpenCode references
|
|
72
|
+
check("every {file:} reference in opencode.jsonc resolves", () => {
|
|
73
|
+
const text = readFileSync(join(root, "opencode.jsonc"), "utf8");
|
|
74
|
+
const refs = [...new Set([...text.matchAll(/\{file:([^}]*)\}/g)].map((m) => m[1]))];
|
|
75
|
+
assert(refs.length > 0, "opencode.jsonc contains no {file:} references at all");
|
|
76
|
+
const dead = refs.filter((ref) => !existsSync(join(root, ref)));
|
|
77
|
+
assert(dead.length === 0, `dead references:\n${dead.join("\n")}`);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// ---- 3. shell syntax
|
|
81
|
+
check("bash -n passes on every .sh file", () => {
|
|
82
|
+
const scripts = filesUnder(root).filter((f) => f.endsWith(".sh"));
|
|
83
|
+
assert(scripts.length > 0, "no .sh files found");
|
|
84
|
+
const broken = [];
|
|
85
|
+
for (const script of scripts) {
|
|
86
|
+
const result = spawnSync("bash", ["-n", script], { encoding: "utf8" });
|
|
87
|
+
if (result.error) throw new Error(`bash could not be started: ${result.error.message}`);
|
|
88
|
+
if (result.status !== 0) broken.push(`${rel(script)}: ${result.stderr.trim()}`);
|
|
89
|
+
}
|
|
90
|
+
assert(broken.length === 0, broken.join("\n"));
|
|
91
|
+
console.log(` ${scripts.length} script(s) checked`);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// ---- 4. package contents
|
|
95
|
+
const libraryPersonas = new Set(["trblazeui.md", "techierag.md"]);
|
|
96
|
+
|
|
97
|
+
// What the three shell scripts copy out of this repository into a project.
|
|
98
|
+
function deployedFiles() {
|
|
99
|
+
const out = [];
|
|
100
|
+
for (const f of filesUnder(join(root, ".tfcore"))) {
|
|
101
|
+
const r = rel(f);
|
|
102
|
+
if (!r.startsWith(".tfcore/.session/")) out.push(r);
|
|
103
|
+
}
|
|
104
|
+
for (const f of filesUnder(join(root, ".claude", "commands"))) {
|
|
105
|
+
if (!libraryPersonas.has(f.split("/").pop())) out.push(rel(f));
|
|
106
|
+
}
|
|
107
|
+
for (const f of filesUnder(join(root, ".opencode", "plugin"))) if (f.endsWith(".js")) out.push(rel(f));
|
|
108
|
+
for (const f of filesUnder(join(root, ".opencode", "command"))) {
|
|
109
|
+
if (f.endsWith(".md") && !libraryPersonas.has(f.split("/").pop())) out.push(rel(f));
|
|
110
|
+
}
|
|
111
|
+
out.push(".codex/config.toml", ".codex/hooks.json");
|
|
112
|
+
for (const f of filesUnder(join(root, ".codex", "rules"))) out.push(rel(f));
|
|
113
|
+
out.push("opencode.jsonc", "WORKFLOW.html");
|
|
114
|
+
return out.filter((r) => !/(^|\/)(\.DS_Store|Thumbs\.db|desktop\.ini)$/.test(r) && !r.endsWith(".bak"));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const mustNotShip = [
|
|
118
|
+
".tfcore/.session", ".claude/settings.json", ".claude/settings.local.json",
|
|
119
|
+
".claude/trblazeui.md", ".claude/techierag.md",
|
|
120
|
+
".claude/commands/trblazeui.md", ".claude/commands/techierag.md",
|
|
121
|
+
".opencode/command/trblazeui.md", ".opencode/command/techierag.md",
|
|
122
|
+
".opencode/node_modules", ".opencode/package.json", ".opencode/package-lock.json", ".opencode/.gitignore",
|
|
123
|
+
".codex/agents", ".agents", ".techierag", ".trblazeui", ".github",
|
|
124
|
+
"scaffold-brownfield.sh", "scaffold-greenfield.sh", "update-framework.sh",
|
|
125
|
+
"docs/TechieFlow-Requirements.md", "docs/TechieFlow-How-It-Works.md", "docs/metrics",
|
|
126
|
+
"DECISIONS.md", "WorkFlow-Context.md", "CodexChanges.md",
|
|
127
|
+
];
|
|
128
|
+
const mustShip = [
|
|
129
|
+
"package.json", "LICENSE", "README.md", "docs/TechieFlow-Installation.md",
|
|
130
|
+
"scripts/install.mjs", "scripts/test-install.mjs", "scripts/validate.mjs",
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
check("npm pack --dry-run succeeds and ships the right files", () => {
|
|
134
|
+
const onWindows = process.platform === "win32";
|
|
135
|
+
const result = process.env.npm_execpath
|
|
136
|
+
? spawnSync(process.execPath, [process.env.npm_execpath, "pack", "--dry-run", "--json"], { cwd: root, encoding: "utf8" })
|
|
137
|
+
: spawnSync(onWindows ? "npm.cmd" : "npm", ["pack", "--dry-run", "--json"], { cwd: root, encoding: "utf8", shell: onWindows });
|
|
138
|
+
if (result.error) throw new Error(`npm could not be started: ${result.error.message}`);
|
|
139
|
+
assert(result.status === 0, `npm pack --dry-run failed:\n${result.stdout}${result.stderr}`);
|
|
140
|
+
const packed = new Set(JSON.parse(result.stdout)[0].files.map((f) => f.path));
|
|
141
|
+
const missing = [...deployedFiles(), ...mustShip].filter((f) => !packed.has(f));
|
|
142
|
+
const leaked = [...packed].filter((p) => mustNotShip.some((bad) => p === bad || p.startsWith(`${bad}/`)));
|
|
143
|
+
const report = [];
|
|
144
|
+
if (missing.length) report.push(`files the shell scripts deploy but the package does not ship:\n${missing.join("\n")}`);
|
|
145
|
+
if (leaked.length) report.push(`files that must not ship:\n${leaked.join("\n")}`);
|
|
146
|
+
assert(report.length === 0, report.join("\n"));
|
|
147
|
+
console.log(` ${packed.size} file(s) in the package`);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
console.log("");
|
|
151
|
+
if (problems.length) {
|
|
152
|
+
console.log(`${passed} check(s) passed, ${problems.length} failed`);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
console.log(`validation passed (${passed} checks)`);
|