deuk-agent-flow 4.0.37 → 5.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/CHANGELOG.ko.md +282 -0
- package/CHANGELOG.md +788 -120
- package/LICENSE +0 -0
- package/README.ko.md +97 -17
- package/README.md +108 -25
- package/bin/deuk-agent-flow.js +11 -13
- package/bin/deuk-agent-rule.js +1 -1
- package/bundled/README.md +3 -0
- package/bundled/deuk-agent-flow.vsix +0 -0
- package/core-rules/AGENTS.md +30 -118
- package/docs/architecture.ko.md +155 -2
- package/docs/architecture.md +155 -2
- package/docs/assets/agentflow-panel-skills.png +0 -0
- package/docs/assets/agentflow-panel.png +0 -0
- package/docs/how-it-works.ko.md +109 -52
- package/docs/how-it-works.md +128 -71
- package/docs/principles.ko.md +68 -68
- package/docs/principles.md +68 -68
- package/docs/usage-guide.ko.md +251 -212
- package/package.json +41 -34
- package/scripts/bundle-vscode-vsix.ts +67 -0
- package/scripts/{cli-args.mjs → cli-args.ts} +49 -12
- package/scripts/cli-init-commands.ts +99 -0
- package/scripts/cli-init-logic.ts +46 -0
- package/scripts/{cli-prompts.mjs → cli-prompts.ts} +19 -34
- package/scripts/{cli-rule-compiler.mjs → cli-rule-compiler.ts} +128 -112
- package/scripts/cli-skill-commands.ts +707 -0
- package/scripts/{cli-telemetry-commands.mjs → cli-telemetry-commands.ts} +25 -22
- package/scripts/cli-ticket-command-shared.ts +4 -0
- package/scripts/cli-ticket-commands.ts +3723 -0
- package/scripts/cli-ticket-index.ts +283 -0
- package/scripts/{cli-ticket-migration.mjs → cli-ticket-migration.ts} +44 -68
- package/scripts/cli-ticket-parser.ts +100 -0
- package/scripts/{cli-usage-commands.mjs → cli-usage-commands.ts} +325 -326
- package/scripts/cli-utils.ts +1560 -0
- package/scripts/cli.ts +695 -0
- package/scripts/{lint-md.mjs → lint-md.ts} +32 -42
- package/scripts/lint-rules.ts +203 -0
- package/scripts/{merge-logic.mjs → merge-logic.ts} +44 -44
- package/scripts/{plan-parser.mjs → plan-parser.ts} +53 -53
- package/templates/MODULE_RULE_TEMPLATE.md +11 -11
- package/templates/PROJECT_RULE.md +46 -47
- package/templates/TICKET_TEMPLATE.ko.md +48 -44
- package/templates/TICKET_TEMPLATE.md +48 -44
- package/templates/project-memory.md +19 -0
- package/templates/project-pilot/CONFORMANCE_GATE_TEMPLATE.md +25 -23
- package/templates/project-pilot/DRIFT_CHECKLIST.md +27 -19
- package/templates/project-pilot/FLOW_CONTRACT_TEMPLATE.md +26 -26
- package/templates/project-pilot/IMPLEMENTATION_MATRIX_TEMPLATE.md +30 -30
- package/templates/project-pilot/INTEGRATION_CONTRACT_TEMPLATE.md +26 -26
- package/templates/project-pilot/OWNER_MAP_TEMPLATE.md +15 -15
- package/templates/project-pilot/PROJECT_PILOT_RULE_TEMPLATE.md +34 -34
- package/templates/project-pilot/REFACTOR_CONTRACT_TEMPLATE.md +32 -32
- package/templates/project-pilot/REMEDIATION_PLAN_TEMPLATE.md +33 -33
- package/templates/rules.d/deukcontext-mcp.md +31 -31
- package/templates/rules.d/platform-coexistence.md +29 -29
- package/templates/skills/context-recall/SKILL.md +3 -1
- package/templates/skills/doc-sync/SKILL.md +111 -0
- package/templates/skills/generated-file-guard/SKILL.md +3 -1
- package/templates/skills/persona-maid/SKILL.md +65 -0
- package/templates/skills/project-pilot/SKILL.md +13 -52
- package/templates/skills/safe-refactor/SKILL.md +3 -1
- package/templates/skills/ticket-status-surface/SKILL.md +17 -0
- package/core-rules/GEMINI.md +0 -7
- package/docs/badges/npm-downloads.json +0 -8
- package/scripts/cli-init-commands.mjs +0 -1750
- package/scripts/cli-init-logic.mjs +0 -64
- package/scripts/cli-skill-commands.mjs +0 -201
- package/scripts/cli-ticket-commands.mjs +0 -2427
- package/scripts/cli-ticket-index.mjs +0 -298
- package/scripts/cli-ticket-parser.mjs +0 -209
- package/scripts/cli-utils.mjs +0 -602
- package/scripts/cli.mjs +0 -256
- package/scripts/lint-rules.mjs +0 -196
- package/scripts/publish-dual-npm.mjs +0 -141
- package/scripts/smoke-npm-docker.mjs +0 -102
- package/scripts/smoke-npm-local.mjs +0 -109
- package/scripts/update-download-badge.mjs +0 -103
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { existsSync, mkdtempSync, readFileSync, rmSync } from "fs";
|
|
3
|
-
import { join, resolve } from "path";
|
|
4
|
-
import { spawnSync } from "child_process";
|
|
5
|
-
import { tmpdir } from "os";
|
|
6
|
-
|
|
7
|
-
const rootDir = resolve(new URL("..", import.meta.url).pathname);
|
|
8
|
-
const aliasDir = join(rootDir, "packages", "deuk-agent-rule");
|
|
9
|
-
const workDir = mkdtempSync(join(tmpdir(), "deuk-agent-flow-docker-smoke-"));
|
|
10
|
-
|
|
11
|
-
function run(command, args, cwd, opts = {}) {
|
|
12
|
-
const shown = [command, ...args].join(" ");
|
|
13
|
-
console.log(`\n$ ${shown}`);
|
|
14
|
-
const result = spawnSync(command, args, {
|
|
15
|
-
cwd,
|
|
16
|
-
encoding: "utf8",
|
|
17
|
-
stdio: opts.capture ? "pipe" : "inherit",
|
|
18
|
-
});
|
|
19
|
-
if (result.status !== 0) {
|
|
20
|
-
if (opts.capture) {
|
|
21
|
-
if (result.stdout) process.stdout.write(result.stdout);
|
|
22
|
-
if (result.stderr) process.stderr.write(result.stderr);
|
|
23
|
-
}
|
|
24
|
-
throw new Error(`command failed: ${shown}`);
|
|
25
|
-
}
|
|
26
|
-
return result;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function readJson(path) {
|
|
30
|
-
return JSON.parse(readFileSync(path, "utf8"));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function pack(cwd) {
|
|
34
|
-
const result = run("npm", ["pack", "--json", "--pack-destination", workDir], cwd, { capture: true });
|
|
35
|
-
const rows = JSON.parse(result.stdout);
|
|
36
|
-
const filename = rows[0]?.filename;
|
|
37
|
-
if (!filename) throw new Error(`npm pack did not return a filename for ${cwd}`);
|
|
38
|
-
const tarball = join(workDir, filename);
|
|
39
|
-
if (!existsSync(tarball)) throw new Error(`packed tarball missing: ${tarball}`);
|
|
40
|
-
return filename;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
const rootPkg = readJson(join(rootDir, "package.json"));
|
|
45
|
-
const aliasPkg = readJson(join(aliasDir, "package.json"));
|
|
46
|
-
|
|
47
|
-
if (rootPkg.name !== "deuk-agent-flow") {
|
|
48
|
-
throw new Error(`expected root package deuk-agent-flow, got ${rootPkg.name}`);
|
|
49
|
-
}
|
|
50
|
-
if (aliasPkg.name !== "deuk-agent-rule") {
|
|
51
|
-
throw new Error(`expected legacy package deuk-agent-rule, got ${aliasPkg.name}`);
|
|
52
|
-
}
|
|
53
|
-
if (aliasPkg.dependencies?.["deuk-agent-flow"] !== rootPkg.version) {
|
|
54
|
-
throw new Error(`deuk-agent-rule must depend on deuk-agent-flow@${rootPkg.version}`);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const flowTarball = pack(rootDir);
|
|
58
|
-
const ruleTarball = pack(aliasDir);
|
|
59
|
-
const image = process.env.DEUK_SMOKE_NODE_IMAGE || "node:20-bookworm";
|
|
60
|
-
const keepDir = Boolean(process.env.DEUK_KEEP_SMOKE_DIR);
|
|
61
|
-
|
|
62
|
-
console.log(`\nSmoke sandbox: ${workDir}`);
|
|
63
|
-
console.log(`Docker image: ${image}`);
|
|
64
|
-
|
|
65
|
-
const script = [
|
|
66
|
-
"set -eu",
|
|
67
|
-
"node --version",
|
|
68
|
-
"npm --version",
|
|
69
|
-
"mkdir -p /tmp/consumer",
|
|
70
|
-
"npm install -g /pkg/" + flowTarball + " /pkg/" + ruleTarball,
|
|
71
|
-
"command -v deuk-agent-flow",
|
|
72
|
-
"command -v deuk-agent-rule",
|
|
73
|
-
"deuk-agent-flow --help >/tmp/deuk-agent-flow-help.txt",
|
|
74
|
-
"deuk-agent-rule --help >/tmp/deuk-agent-rule-help.txt",
|
|
75
|
-
"cd /tmp/consumer",
|
|
76
|
-
"mkdir -p .codex",
|
|
77
|
-
"deuk-agent-flow init --non-interactive --workflow execute --docs-language ko --agents skip",
|
|
78
|
-
"test -f .codex/AGENTS.md",
|
|
79
|
-
"test -f PROJECT_RULE.md",
|
|
80
|
-
"test -d .deuk-agent",
|
|
81
|
-
"test ! -d .deuk-agent/templates",
|
|
82
|
-
"test -d .deuk-agent/skill-templates",
|
|
83
|
-
].join("\n");
|
|
84
|
-
|
|
85
|
-
run("docker", [
|
|
86
|
-
"run",
|
|
87
|
-
"--rm",
|
|
88
|
-
"-v",
|
|
89
|
-
`${workDir}:/pkg:ro`,
|
|
90
|
-
image,
|
|
91
|
-
"bash",
|
|
92
|
-
"-lc",
|
|
93
|
-
script,
|
|
94
|
-
], rootDir);
|
|
95
|
-
|
|
96
|
-
console.log("\nDocker npm smoke ok");
|
|
97
|
-
if (keepDir) console.log(`Kept smoke sandbox: ${workDir}`);
|
|
98
|
-
} finally {
|
|
99
|
-
if (!process.env.DEUK_KEEP_SMOKE_DIR) {
|
|
100
|
-
rmSync(workDir, { recursive: true, force: true });
|
|
101
|
-
}
|
|
102
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { existsSync, mkdtempSync, readFileSync, rmSync, statSync } from "fs";
|
|
3
|
-
import { delimiter, join, resolve } from "path";
|
|
4
|
-
import { spawnSync } from "child_process";
|
|
5
|
-
import { tmpdir } from "os";
|
|
6
|
-
|
|
7
|
-
const rootDir = resolve(new URL("..", import.meta.url).pathname);
|
|
8
|
-
const aliasDir = join(rootDir, "packages", "deuk-agent-rule");
|
|
9
|
-
const workDir = mkdtempSync(join(tmpdir(), "deuk-agent-flow-local-smoke-"));
|
|
10
|
-
const prefixDir = join(workDir, "prefix");
|
|
11
|
-
|
|
12
|
-
function run(command, args, cwd, opts = {}) {
|
|
13
|
-
const shown = [command, ...args].join(" ");
|
|
14
|
-
console.log(`\n$ ${shown}`);
|
|
15
|
-
const result = spawnSync(command, args, {
|
|
16
|
-
cwd,
|
|
17
|
-
encoding: "utf8",
|
|
18
|
-
env: opts.env || process.env,
|
|
19
|
-
stdio: opts.capture ? "pipe" : "inherit",
|
|
20
|
-
});
|
|
21
|
-
if (result.status !== 0) {
|
|
22
|
-
if (opts.capture) {
|
|
23
|
-
if (result.stdout) process.stdout.write(result.stdout);
|
|
24
|
-
if (result.stderr) process.stderr.write(result.stderr);
|
|
25
|
-
}
|
|
26
|
-
throw new Error(`command failed: ${shown}`);
|
|
27
|
-
}
|
|
28
|
-
return result;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function readJson(path) {
|
|
32
|
-
return JSON.parse(readFileSync(path, "utf8"));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function pack(cwd, expected) {
|
|
36
|
-
const result = run("npm", ["pack", "--json", "--pack-destination", workDir], cwd, { capture: true });
|
|
37
|
-
const rows = JSON.parse(result.stdout);
|
|
38
|
-
const row = rows[0];
|
|
39
|
-
const filename = row?.filename;
|
|
40
|
-
if (!filename) throw new Error(`npm pack did not return a filename for ${cwd}`);
|
|
41
|
-
const tarball = join(workDir, filename);
|
|
42
|
-
if (!existsSync(tarball)) throw new Error(`packed tarball missing: ${tarball}`);
|
|
43
|
-
|
|
44
|
-
const fileSet = new Set((row.files || []).map(file => file.path));
|
|
45
|
-
for (const path of expected.files) {
|
|
46
|
-
if (!fileSet.has(path)) throw new Error(`${expected.name} tarball missing required file: ${path}`);
|
|
47
|
-
}
|
|
48
|
-
return { filename, tarball };
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function globalBinDir(prefix) {
|
|
52
|
-
return process.platform === "win32" ? prefix : join(prefix, "bin");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function assertGlobalCommand(binDir, name) {
|
|
56
|
-
const script = process.platform === "win32" ? join(binDir, `${name}.cmd`) : join(binDir, name);
|
|
57
|
-
if (!existsSync(script)) throw new Error(`global command shim missing: ${script}`);
|
|
58
|
-
if (process.platform !== "win32") {
|
|
59
|
-
const mode = statSync(script).mode;
|
|
60
|
-
if ((mode & 0o111) === 0) throw new Error(`global command is not executable: ${script}`);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
const rootPkg = readJson(join(rootDir, "package.json"));
|
|
66
|
-
const aliasPkg = readJson(join(aliasDir, "package.json"));
|
|
67
|
-
if (aliasPkg.dependencies?.["deuk-agent-flow"] !== rootPkg.version) {
|
|
68
|
-
throw new Error(`deuk-agent-rule must depend on deuk-agent-flow@${rootPkg.version}`);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const flow = pack(rootDir, {
|
|
72
|
-
name: "deuk-agent-flow",
|
|
73
|
-
files: [
|
|
74
|
-
"bin/deuk-agent-flow.js",
|
|
75
|
-
"bin/deuk-agent-rule.js",
|
|
76
|
-
"scripts/cli.mjs",
|
|
77
|
-
"scripts/cli-ticket-commands.mjs",
|
|
78
|
-
"scripts/lint-md.mjs",
|
|
79
|
-
"scripts/lint-rules.mjs",
|
|
80
|
-
"package.json",
|
|
81
|
-
],
|
|
82
|
-
});
|
|
83
|
-
const rule = pack(aliasDir, {
|
|
84
|
-
name: "deuk-agent-rule",
|
|
85
|
-
files: [
|
|
86
|
-
"bin/deuk-agent-rule.js",
|
|
87
|
-
"package.json",
|
|
88
|
-
"README.md",
|
|
89
|
-
],
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
run("npm", ["install", "-g", "--prefix", prefixDir, flow.tarball, rule.tarball], rootDir);
|
|
93
|
-
|
|
94
|
-
const binDir = globalBinDir(prefixDir);
|
|
95
|
-
const pathEnv = [binDir, process.env.PATH || ""].join(delimiter);
|
|
96
|
-
const env = { ...process.env, PATH: pathEnv };
|
|
97
|
-
|
|
98
|
-
for (const command of ["deuk-agent-flow", "deukagentflow", "deuk-agent-rule", "deukagentrule"]) {
|
|
99
|
-
assertGlobalCommand(binDir, command);
|
|
100
|
-
run(command, ["--help"], rootDir, { env, capture: true });
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
console.log(`\nLocal npm install smoke ok (${process.platform})`);
|
|
104
|
-
console.log(`Checked tarballs: ${flow.filename}, ${rule.filename}`);
|
|
105
|
-
} finally {
|
|
106
|
-
if (!process.env.DEUK_KEEP_SMOKE_DIR) {
|
|
107
|
-
rmSync(workDir, { recursive: true, force: true });
|
|
108
|
-
}
|
|
109
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { mkdirSync, writeFileSync } from "fs";
|
|
3
|
-
import { dirname, join } from "path";
|
|
4
|
-
|
|
5
|
-
const DEFAULT_PACKAGES = ["deuk-agent-flow", "deuk-agent-rule"];
|
|
6
|
-
const DEFAULT_RANGE = "last-month";
|
|
7
|
-
const DEFAULT_OUT = "docs/badges/npm-downloads.json";
|
|
8
|
-
const DEFAULT_CANONICAL_PACKAGE = "deuk-agent-flow";
|
|
9
|
-
|
|
10
|
-
function parseArgs(argv) {
|
|
11
|
-
const opts = {
|
|
12
|
-
packages: [...DEFAULT_PACKAGES],
|
|
13
|
-
range: DEFAULT_RANGE,
|
|
14
|
-
out: DEFAULT_OUT,
|
|
15
|
-
canonicalPackage: DEFAULT_CANONICAL_PACKAGE,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
19
|
-
const arg = argv[i];
|
|
20
|
-
if (arg === "--packages") {
|
|
21
|
-
opts.packages = argv[++i].split(",").map((name) => name.trim()).filter(Boolean);
|
|
22
|
-
} else if (arg === "--range") {
|
|
23
|
-
opts.range = argv[++i];
|
|
24
|
-
} else if (arg === "--out") {
|
|
25
|
-
opts.out = argv[++i];
|
|
26
|
-
} else if (arg === "--canonical") {
|
|
27
|
-
opts.canonicalPackage = argv[++i];
|
|
28
|
-
} else {
|
|
29
|
-
throw new Error(`Unknown argument: ${arg}`);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (opts.packages.length === 0) {
|
|
34
|
-
throw new Error("--packages must include at least one npm package name");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return opts;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function fetchDownloads(packageName, range) {
|
|
41
|
-
const url = `https://api.npmjs.org/downloads/point/${encodeURIComponent(range)}/${encodeURIComponent(packageName)}`;
|
|
42
|
-
const res = await fetch(url);
|
|
43
|
-
|
|
44
|
-
if (res.status === 404) {
|
|
45
|
-
return { package: packageName, downloads: 0, missing: true };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!res.ok) {
|
|
49
|
-
throw new Error(`npm downloads request failed for ${packageName}: ${res.status} ${res.statusText}`);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const body = await res.json();
|
|
53
|
-
return {
|
|
54
|
-
package: packageName,
|
|
55
|
-
downloads: Number(body.downloads || 0),
|
|
56
|
-
missing: false,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function formatDownloads(value) {
|
|
61
|
-
return new Intl.NumberFormat("en", {
|
|
62
|
-
notation: "compact",
|
|
63
|
-
maximumFractionDigits: value >= 1000 ? 1 : 0,
|
|
64
|
-
}).format(value);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export async function buildDownloadsBadge(opts) {
|
|
68
|
-
const canonicalPackage = opts.canonicalPackage || opts.packages[0];
|
|
69
|
-
const packages = await Promise.all(opts.packages.map((name) => fetchDownloads(name, opts.range)));
|
|
70
|
-
const total = packages.reduce((sum, pkg) => sum + pkg.downloads, 0);
|
|
71
|
-
const canonical = packages.find((pkg) => pkg.package === canonicalPackage) || packages[0];
|
|
72
|
-
const aliases = packages.filter((pkg) => pkg.package !== canonical.package);
|
|
73
|
-
const aliasTotal = aliases.reduce((sum, pkg) => sum + pkg.downloads, 0);
|
|
74
|
-
void canonical;
|
|
75
|
-
void aliasTotal;
|
|
76
|
-
void aliases;
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
schemaVersion: 1,
|
|
80
|
-
label: "deuk-flow downloads",
|
|
81
|
-
message: `${formatDownloads(total)}/${opts.range}`,
|
|
82
|
-
color: "2f6fed",
|
|
83
|
-
namedLogo: "npm",
|
|
84
|
-
cacheSeconds: 86400,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export async function main(argv = process.argv.slice(2)) {
|
|
89
|
-
const opts = parseArgs(argv);
|
|
90
|
-
const badge = await buildDownloadsBadge(opts);
|
|
91
|
-
const outPath = join(process.cwd(), opts.out);
|
|
92
|
-
|
|
93
|
-
mkdirSync(dirname(outPath), { recursive: true });
|
|
94
|
-
writeFileSync(outPath, JSON.stringify(badge, null, 2) + "\n", "utf8");
|
|
95
|
-
console.log(`Wrote ${opts.out}: ${badge.message}`);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
99
|
-
main().catch((error) => {
|
|
100
|
-
console.error(error.message);
|
|
101
|
-
process.exit(1);
|
|
102
|
-
});
|
|
103
|
-
}
|