deuk-agent-flow 4.2.7 → 5.0.4
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 +277 -0
- package/CHANGELOG.md +794 -124
- 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 -120
- 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 +60 -45
- package/scripts/bundle-vscode-vsix.ts +67 -0
- package/scripts/{cli-args.mjs → cli-args.ts} +49 -12
- package/scripts/cli-context-commands.ts +35 -0
- package/scripts/cli-init-claude.ts +179 -0
- package/scripts/cli-init-commands.ts +99 -0
- package/scripts/cli-init-core.ts +89 -0
- package/scripts/cli-init-instructions.ts +489 -0
- package/scripts/cli-init-logic.ts +46 -0
- package/scripts/cli-init-migrate.ts +504 -0
- package/scripts/cli-init-workspace.ts +63 -0
- package/scripts/cli-locales.ts +85 -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 +709 -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 +3781 -0
- package/scripts/cli-ticket-docmeta.ts +103 -0
- package/scripts/cli-ticket-document.ts +153 -0
- package/scripts/cli-ticket-evidence.ts +312 -0
- package/scripts/cli-ticket-home.ts +449 -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-ticket-scan.ts +102 -0
- package/scripts/cli-ticket-surface.ts +56 -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/oss-prepack.js +32 -0
- package/scripts/out/scripts/bundle-vscode-vsix.js +68 -0
- package/scripts/out/scripts/bundle-vscode-vsix.js.map +1 -0
- package/scripts/out/scripts/cli-args.js +374 -0
- package/scripts/out/scripts/cli-args.js.map +1 -0
- package/scripts/out/scripts/cli-context-commands.js +31 -0
- package/scripts/out/scripts/cli-context-commands.js.map +1 -0
- package/scripts/out/scripts/cli-init-claude.js +176 -0
- package/scripts/out/scripts/cli-init-claude.js.map +1 -0
- package/scripts/out/scripts/cli-init-commands.js +87 -0
- package/scripts/out/scripts/cli-init-commands.js.map +1 -0
- package/scripts/out/scripts/cli-init-core.js +89 -0
- package/scripts/out/scripts/cli-init-core.js.map +1 -0
- package/scripts/out/scripts/cli-init-instructions.js +460 -0
- package/scripts/out/scripts/cli-init-instructions.js.map +1 -0
- package/scripts/out/scripts/cli-init-logic.js +41 -0
- package/scripts/out/scripts/cli-init-logic.js.map +1 -0
- package/scripts/out/scripts/cli-init-migrate.js +497 -0
- package/scripts/out/scripts/cli-init-migrate.js.map +1 -0
- package/scripts/out/scripts/cli-init-workspace.js +57 -0
- package/scripts/out/scripts/cli-init-workspace.js.map +1 -0
- package/scripts/out/scripts/cli-locales.js +83 -0
- package/scripts/out/scripts/cli-locales.js.map +1 -0
- package/scripts/out/scripts/cli-prompts.js +101 -0
- package/scripts/out/scripts/cli-prompts.js.map +1 -0
- package/scripts/out/scripts/cli-rule-compiler.js +121 -0
- package/scripts/out/scripts/cli-rule-compiler.js.map +1 -0
- package/scripts/out/scripts/cli-skill-commands.js +708 -0
- package/scripts/out/scripts/cli-skill-commands.js.map +1 -0
- package/scripts/out/scripts/cli-telemetry-commands.js +604 -0
- package/scripts/out/scripts/cli-telemetry-commands.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-command-shared.js +2 -0
- package/scripts/out/scripts/cli-ticket-command-shared.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-commands.js +3530 -0
- package/scripts/out/scripts/cli-ticket-commands.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-docmeta.js +90 -0
- package/scripts/out/scripts/cli-ticket-docmeta.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-document.js +121 -0
- package/scripts/out/scripts/cli-ticket-document.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-evidence.js +286 -0
- package/scripts/out/scripts/cli-ticket-evidence.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-home.js +440 -0
- package/scripts/out/scripts/cli-ticket-home.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-index.js +272 -0
- package/scripts/out/scripts/cli-ticket-index.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-migration.js +261 -0
- package/scripts/out/scripts/cli-ticket-migration.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-parser.js +90 -0
- package/scripts/out/scripts/cli-ticket-parser.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-scan.js +93 -0
- package/scripts/out/scripts/cli-ticket-scan.js.map +1 -0
- package/scripts/out/scripts/cli-ticket-surface.js +53 -0
- package/scripts/out/scripts/cli-ticket-surface.js.map +1 -0
- package/scripts/out/scripts/cli-usage-commands.js +310 -0
- package/scripts/out/scripts/cli-usage-commands.js.map +1 -0
- package/scripts/out/scripts/cli-utils.js +1544 -0
- package/scripts/out/scripts/cli-utils.js.map +1 -0
- package/scripts/out/scripts/cli.js +696 -0
- package/scripts/out/scripts/cli.js.map +1 -0
- package/scripts/out/scripts/lint-md.js +238 -0
- package/scripts/out/scripts/lint-md.js.map +1 -0
- package/scripts/out/scripts/lint-rules.js +193 -0
- package/scripts/out/scripts/lint-rules.js.map +1 -0
- package/scripts/out/scripts/merge-logic.js +38 -0
- package/scripts/out/scripts/merge-logic.js.map +1 -0
- package/scripts/out/scripts/plan-parser.js +52 -0
- package/scripts/out/scripts/plan-parser.js.map +1 -0
- package/scripts/out/scripts/ticket-machine.js +94 -0
- package/scripts/out/scripts/ticket-machine.js.map +1 -0
- package/scripts/out/scripts/ticket-workflow.js +498 -0
- package/scripts/out/scripts/ticket-workflow.js.map +1 -0
- package/scripts/{plan-parser.mjs → plan-parser.ts} +53 -53
- package/scripts/ticket-machine.ts +99 -0
- package/scripts/ticket-workflow.ts +544 -0
- 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 -25
- package/templates/project-pilot/DRIFT_CHECKLIST.md +27 -27
- 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 +14 -63
- package/templates/skills/role-closer/SKILL.md +27 -0
- package/templates/skills/role-implementer/SKILL.md +30 -0
- package/templates/skills/role-planner/SKILL.md +29 -0
- package/templates/skills/role-qa-verifier/SKILL.md +30 -0
- package/templates/skills/safe-refactor/SKILL.md +3 -1
- package/templates/skills/ticket-status-surface/SKILL.md +17 -0
- package/NOTICE.md +0 -19
- package/core-rules/GEMINI.md +0 -7
- package/docs/npm-publish-guide.ko.md +0 -70
- package/scripts/cli-init-commands.mjs +0 -1759
- package/scripts/cli-init-logic.mjs +0 -64
- package/scripts/cli-skill-commands.mjs +0 -212
- package/scripts/cli-ticket-command-shared.mjs +0 -60
- package/scripts/cli-ticket-commands.mjs +0 -2474
- package/scripts/cli-ticket-index.mjs +0 -322
- package/scripts/cli-ticket-parser.mjs +0 -210
- package/scripts/cli-utils.mjs +0 -602
- package/scripts/cli.mjs +0 -256
- package/scripts/lint-rules.mjs +0 -197
- package/scripts/publish-dual-npm.mjs +0 -141
- package/scripts/smoke-npm-docker.mjs +0 -102
- package/scripts/smoke-npm-local.mjs +0 -110
- package/scripts/update-download-badge.mjs +0 -103
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deuk-agent-flow",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.4",
|
|
4
4
|
"description": "Keep AI coding work from vanishing between chats: repo-owned tickets, scope, verification, and memory for AGENTS.md-powered agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents-md",
|
|
@@ -22,73 +22,85 @@
|
|
|
22
22
|
"license": "Apache-2.0",
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
|
25
|
-
"url": "https://github.com/joygram/DeukAgentFlow.git"
|
|
25
|
+
"url": "git+https://github.com/joygram/DeukAgentFlow.git"
|
|
26
26
|
},
|
|
27
27
|
"bugs": {
|
|
28
28
|
"url": "https://github.com/joygram/DeukAgentFlow/issues"
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/joygram/DeukAgentFlow#readme",
|
|
31
31
|
"files": [
|
|
32
|
+
"LICENSE",
|
|
32
33
|
"bin/**/*",
|
|
33
34
|
"core-rules/**/*",
|
|
34
35
|
"docs/architecture.md",
|
|
35
36
|
"docs/architecture.ko.md",
|
|
37
|
+
"docs/badges/**/*",
|
|
36
38
|
"docs/how-it-works.md",
|
|
37
39
|
"docs/how-it-works.ko.md",
|
|
38
40
|
"docs/principles.md",
|
|
39
41
|
"docs/principles.ko.md",
|
|
40
|
-
"docs/npm-publish-guide.ko.md",
|
|
41
42
|
"docs/usage-guide.ko.md",
|
|
42
43
|
"docs/assets/**/*",
|
|
43
|
-
"
|
|
44
|
+
"bundled/**/*",
|
|
44
45
|
"templates/**/*",
|
|
45
|
-
"scripts/
|
|
46
|
-
"scripts/cli
|
|
47
|
-
"scripts/cli-
|
|
48
|
-
"scripts/cli-
|
|
49
|
-
"scripts/cli-init-
|
|
50
|
-
"scripts/cli-
|
|
51
|
-
"scripts/cli-
|
|
52
|
-
"scripts/cli-
|
|
53
|
-
"scripts/cli-
|
|
54
|
-
"scripts/cli-
|
|
55
|
-
"scripts/cli-
|
|
56
|
-
"scripts/cli-
|
|
57
|
-
"scripts/cli-
|
|
58
|
-
"scripts/cli-
|
|
59
|
-
"scripts/cli-
|
|
60
|
-
"scripts/
|
|
61
|
-
"scripts/
|
|
62
|
-
"scripts/
|
|
63
|
-
"scripts/
|
|
64
|
-
"scripts/
|
|
65
|
-
"scripts/
|
|
66
|
-
"scripts/
|
|
67
|
-
"scripts/
|
|
46
|
+
"scripts/bundle-vscode-vsix.ts",
|
|
47
|
+
"scripts/cli.ts",
|
|
48
|
+
"scripts/cli-args.ts",
|
|
49
|
+
"scripts/cli-context-commands.ts",
|
|
50
|
+
"scripts/cli-init-claude.ts",
|
|
51
|
+
"scripts/cli-init-commands.ts",
|
|
52
|
+
"scripts/cli-init-core.ts",
|
|
53
|
+
"scripts/cli-init-instructions.ts",
|
|
54
|
+
"scripts/cli-init-logic.ts",
|
|
55
|
+
"scripts/cli-init-migrate.ts",
|
|
56
|
+
"scripts/cli-init-workspace.ts",
|
|
57
|
+
"scripts/cli-locales.ts",
|
|
58
|
+
"scripts/cli-prompts.ts",
|
|
59
|
+
"scripts/cli-rule-compiler.ts",
|
|
60
|
+
"scripts/cli-skill-commands.ts",
|
|
61
|
+
"scripts/cli-telemetry-commands.ts",
|
|
62
|
+
"scripts/cli-ticket-command-shared.ts",
|
|
63
|
+
"scripts/cli-ticket-commands.ts",
|
|
64
|
+
"scripts/cli-ticket-docmeta.ts",
|
|
65
|
+
"scripts/cli-ticket-document.ts",
|
|
66
|
+
"scripts/cli-ticket-evidence.ts",
|
|
67
|
+
"scripts/cli-ticket-home.ts",
|
|
68
|
+
"scripts/cli-ticket-index.ts",
|
|
69
|
+
"scripts/cli-ticket-migration.ts",
|
|
70
|
+
"scripts/cli-ticket-parser.ts",
|
|
71
|
+
"scripts/cli-ticket-scan.ts",
|
|
72
|
+
"scripts/cli-ticket-surface.ts",
|
|
73
|
+
"scripts/cli-usage-commands.ts",
|
|
74
|
+
"scripts/cli-utils.ts",
|
|
75
|
+
"scripts/lint-md.ts",
|
|
76
|
+
"scripts/lint-rules.ts",
|
|
77
|
+
"scripts/merge-logic.ts",
|
|
78
|
+
"scripts/plan-parser.ts",
|
|
79
|
+
"scripts/ticket-machine.ts",
|
|
80
|
+
"scripts/ticket-workflow.ts",
|
|
81
|
+
"scripts/oss-prepack.js",
|
|
82
|
+
"scripts/out/**/*",
|
|
68
83
|
"README.md",
|
|
69
84
|
"README.ko.md",
|
|
70
85
|
"CHANGELOG.md",
|
|
71
86
|
"CHANGELOG.ko.md"
|
|
72
87
|
],
|
|
73
88
|
"scripts": {
|
|
74
|
-
"
|
|
75
|
-
"bump
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"publish": "
|
|
83
|
-
"publish:dry": "
|
|
84
|
-
"smoke:npm:local": "node scripts/smoke-npm-local.
|
|
85
|
-
"smoke:npm:docker": "node scripts/smoke-npm-docker.
|
|
86
|
-
"publish:bootstrap": "node scripts/publish-dual-npm.mjs --alias-only",
|
|
87
|
-
"publish:bootstrap:dry": "node scripts/publish-dual-npm.mjs --alias-only --dry-run",
|
|
88
|
-
"badge:downloads": "node scripts/update-download-badge.mjs"
|
|
89
|
+
"dev:install": "npx tsc -p tsconfig.scripts.json && node scripts/out/scripts/dev-install.js",
|
|
90
|
+
"dev:install:no-bump": "npx tsc -p tsconfig.scripts.json && node scripts/out/scripts/dev-install.js --no-bump",
|
|
91
|
+
"build:vscode": "npx tsc -p tsconfig.scripts.json && node scripts/out/scripts/bundle-vscode-vsix.js",
|
|
92
|
+
"prepack": "node scripts/oss-prepack.js",
|
|
93
|
+
"install:vscode": "node scripts/out/scripts/install-vscode-vsix.js --all",
|
|
94
|
+
"install:vscode:desktop": "node scripts/out/scripts/install-vscode-vsix.js --desktop",
|
|
95
|
+
"install:vscode:server": "node scripts/out/scripts/install-vscode-vsix.js --server",
|
|
96
|
+
"lint:md": "node scripts/out/scripts/lint-md.js",
|
|
97
|
+
"publish": "npm publish --access public",
|
|
98
|
+
"publish:dry": "npm publish --access public --dry-run",
|
|
99
|
+
"smoke:npm:local": "node scripts/out/scripts/smoke-npm-local.js",
|
|
100
|
+
"smoke:npm:docker": "node scripts/out/scripts/smoke-npm-docker.js"
|
|
89
101
|
},
|
|
90
102
|
"engines": {
|
|
91
|
-
"node": ">=
|
|
103
|
+
"node": ">=20"
|
|
92
104
|
},
|
|
93
105
|
"bin": {
|
|
94
106
|
"deuk-agent-flow": "./bin/deuk-agent-flow.js",
|
|
@@ -97,10 +109,13 @@
|
|
|
97
109
|
"deukagentrule": "./bin/deuk-agent-rule.js"
|
|
98
110
|
},
|
|
99
111
|
"devDependencies": {
|
|
100
|
-
"
|
|
112
|
+
"typescript": "^6.0.3",
|
|
113
|
+
"@types/node": "^25.9.3"
|
|
101
114
|
},
|
|
102
115
|
"dependencies": {
|
|
103
116
|
"ejs": "^5.0.2",
|
|
117
|
+
"xstate": "^5.32.1",
|
|
104
118
|
"yaml": "^2.8.3"
|
|
105
|
-
}
|
|
119
|
+
},
|
|
120
|
+
"type": "module"
|
|
106
121
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Packs vscode-extension into bundled/deuk-agent-flow.vsix for the npm tarball.
|
|
4
|
+
* Temporarily sets the extension package.json version to the root package version.
|
|
5
|
+
*/
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
import { execSync } from "child_process";
|
|
9
|
+
import { CliOpts, makePath, resolvePackageRoot } from "./cli-utils.js";
|
|
10
|
+
|
|
11
|
+
const root = resolvePackageRoot({ fromUrl: import.meta.url });
|
|
12
|
+
const extDir = makePath(root, 'vscode-extension');
|
|
13
|
+
const extPkgPath = makePath(extDir, 'package.json');
|
|
14
|
+
const bundledDir = makePath(root, 'bundled');
|
|
15
|
+
const vsixPath = makePath(bundledDir, 'deuk-agent-flow.vsix');
|
|
16
|
+
const installAfterBundle = process.argv.includes('--install') || process.env.DEUK_AGENT_FLOW_INSTALL_VSIX === '1';
|
|
17
|
+
const skipCompile = process.argv.includes('--skip-compile') || process.env.DEUK_AGENT_FLOW_SKIP_COMPILE === '1';
|
|
18
|
+
|
|
19
|
+
const rootPkg = JSON.parse(fs.readFileSync(makePath(root, 'package.json'), 'utf8'));
|
|
20
|
+
const extPkg = JSON.parse(fs.readFileSync(extPkgPath, 'utf8'));
|
|
21
|
+
const savedPrepublish = extPkg.scripts?.['vscode:prepublish'];
|
|
22
|
+
extPkg.version = rootPkg.version;
|
|
23
|
+
extPkg.scripts = {
|
|
24
|
+
...extPkg.scripts,
|
|
25
|
+
'vscode:prepublish': 'tsc -p ./',
|
|
26
|
+
};
|
|
27
|
+
fs.writeFileSync(extPkgPath, JSON.stringify(extPkg, null, 2) + '\n');
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
if (!fs.existsSync(bundledDir)) fs.mkdirSync(bundledDir, { recursive: true });
|
|
31
|
+
execSync('npm install --no-audit --no-fund --loglevel=silent', { cwd: extDir, stdio: 'inherit', shell: true } as any);
|
|
32
|
+
if (!skipCompile) {
|
|
33
|
+
execSync('npm run compile', { cwd: extDir, stdio: 'inherit' } as any);
|
|
34
|
+
}
|
|
35
|
+
const vsceBin = makePath(extDir, 'node_modules', '.bin', process.platform === 'win32' ? 'vsce.cmd' : 'vsce');
|
|
36
|
+
if (!fs.existsSync(vsceBin)) {
|
|
37
|
+
console.error('[deuk-agent-flow] @vscode/vsce missing. Run npm install in vscode-extension.');
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
const q = (s) => (s.includes(' ') ? `"${s.replace(/"/g, '\\"')}"` : s);
|
|
41
|
+
execSync(`${q(vsceBin)} package --no-dependencies --out ${q(vsixPath)}`, { cwd: extDir, input: 'y\n', stdio: ['pipe', 'inherit', 'inherit'], shell: true } as any);
|
|
42
|
+
if (!fs.existsSync(vsixPath)) {
|
|
43
|
+
console.error('[deuk-agent-flow] bundle-vscode: expected VSIX missing:', vsixPath);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
console.log('[deuk-agent-flow] bundled VS Code extension:', vsixPath);
|
|
47
|
+
if (installAfterBundle) {
|
|
48
|
+
if (process.platform === 'win32') {
|
|
49
|
+
// Windows node 컨텍스트: WSL bash 스크립트로 WSL 파일시스템에 직접 설치
|
|
50
|
+
const wslScript = execSync(`wsl.exe wslpath -u "${root.replace(/\\/g, '/')}/scripts/install-vsix-wsl.sh"`, { encoding: 'utf8', shell: true } as any).toString().trim();
|
|
51
|
+
execSync(`wsl.exe bash "${wslScript}"`, { stdio: 'inherit', shell: true } as any);
|
|
52
|
+
} else {
|
|
53
|
+
execSync('node scripts/out/scripts/install-vscode-vsix.js --all', { cwd: root, stdio: 'inherit', shell: true } as any);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} finally {
|
|
57
|
+
// #version-sync: keep the extension package.json version pinned to the root version
|
|
58
|
+
// (do NOT restore savedVer) so vscode-extension/package.json auto-tracks the root on
|
|
59
|
+
// every bundle instead of drifting back to a stale value. Only prepublish is temporary.
|
|
60
|
+
extPkg.version = rootPkg.version;
|
|
61
|
+
if (savedPrepublish === undefined) {
|
|
62
|
+
delete extPkg.scripts['vscode:prepublish'];
|
|
63
|
+
} else {
|
|
64
|
+
extPkg.scripts['vscode:prepublish'] = savedPrepublish;
|
|
65
|
+
}
|
|
66
|
+
fs.writeFileSync(extPkgPath, JSON.stringify(extPkg, null, 2) + '\n');
|
|
67
|
+
}
|
|
@@ -1,12 +1,35 @@
|
|
|
1
|
+
// Parse a phase token from --phase/--to. Accepts "2", "phase2", "phase 2", "end", "start".
|
|
2
|
+
// Returns NaN when no digit is present and not a known named state so callers can detect
|
|
3
|
+
// a malformed value (e.g. "--to phaseX") instead of silently advancing. (#635)
|
|
4
|
+
const NAMED_PHASE_MAP = { start: 1, phase1: 1, phase2: 2, phase3: 3, phase4: 4, end: 4 };
|
|
5
|
+
function parsePhaseToken(raw) {
|
|
6
|
+
const s = String(raw ?? "").trim().toLowerCase();
|
|
7
|
+
if (NAMED_PHASE_MAP[s] !== undefined) return NAMED_PHASE_MAP[s];
|
|
8
|
+
const m = s.match(/\d+/);
|
|
9
|
+
return m ? Number(m[0]) : NaN;
|
|
10
|
+
}
|
|
11
|
+
|
|
1
12
|
export function parseTicketArgs(argv) {
|
|
2
|
-
const
|
|
13
|
+
const invocationCwd = process.cwd();
|
|
14
|
+
const out: Record<string, any> = { cwd: invocationCwd, invocationCwd, dryRun: false, nonInteractive: false, limit: 20 };
|
|
3
15
|
for (let i = 0; i < argv.length; i++) {
|
|
4
16
|
const a = argv[i];
|
|
5
|
-
if (a === "--cwd")
|
|
17
|
+
if (a === "--cwd") {
|
|
18
|
+
out.cwd = argv[++i];
|
|
19
|
+
out.cwdExplicit = true;
|
|
20
|
+
}
|
|
6
21
|
else if (a === "--dry-run") out.dryRun = true;
|
|
22
|
+
else if (a === "--apply") out.apply = true;
|
|
7
23
|
else if (a === "--non-interactive") out.nonInteractive = true;
|
|
8
|
-
else if (a === "--
|
|
24
|
+
else if (a === "--id" || a === "--ticket") out.ticketId = argv[++i];
|
|
25
|
+
else if (a === "--title") out.title = argv[++i];
|
|
26
|
+
else if (a === "--platform") out.platform = argv[++i];
|
|
9
27
|
else if (a === "--group") out.group = argv[++i];
|
|
28
|
+
else if (a === "--parent" || a === "--main-ticket") out.parent = argv[++i];
|
|
29
|
+
else if (a === "--workspace") out.workspace = argv[++i];
|
|
30
|
+
else if (a === "--allow-cwd-target") {
|
|
31
|
+
throw new Error("ticket commands no longer support cwd-based target selection. Use --workspace <id>.");
|
|
32
|
+
}
|
|
10
33
|
else if (a === "--project") out.project = argv[++i];
|
|
11
34
|
else if (a === "--content") out.content = argv[++i];
|
|
12
35
|
else if (a === "--content-file") out.contentFile = argv[++i];
|
|
@@ -19,7 +42,10 @@ export function parseTicketArgs(argv) {
|
|
|
19
42
|
else if (a === "--latest" || a === "-l") out.latest = true;
|
|
20
43
|
else if (a === "--path-only") out.pathOnly = true;
|
|
21
44
|
else if (a === "--print-content") out.printContent = true;
|
|
45
|
+
else if (a === "--with-total") out.withTotal = true;
|
|
46
|
+
else if (a === "--takeover") out.takeover = true;
|
|
22
47
|
else if (a === "--all") out.all = true;
|
|
48
|
+
else if (a === "--active") out.active = true;
|
|
23
49
|
else if (a === "--status") out.status = argv[++i];
|
|
24
50
|
else if (a === "--archived") out.archived = true;
|
|
25
51
|
else if (a === "--priority") out.priority = argv[++i];
|
|
@@ -33,13 +59,12 @@ export function parseTicketArgs(argv) {
|
|
|
33
59
|
else if (a === "--docs-language") out.docsLanguage = argv[++i];
|
|
34
60
|
else if (a === "--workflow") out.workflowMode = argv[++i];
|
|
35
61
|
else if (a === "--approval") out.approval = argv[++i];
|
|
36
|
-
else if (a === "--ticket-started") out.ticketStarted = true;
|
|
37
|
-
else if (a === "--ticket-reviewed") out.ticketReviewed = true;
|
|
38
62
|
else if (a === "--evidence") out.evidence = argv[++i];
|
|
39
63
|
else if (a === "--skip-phase0") out.skipPhase0 = true;
|
|
40
64
|
else if (a === "--summary") out.summary = argv[++i];
|
|
65
|
+
else if (a === "--type") out.ticketType = argv[++i];
|
|
41
66
|
else if (a === "--tags") out.tags = argv[++i];
|
|
42
|
-
else if (a === "--phase") out.phase =
|
|
67
|
+
else if (a === "--phase" || a === "--to") { out.phase = parsePhaseToken(argv[++i]); out.phaseRequested = true; }
|
|
43
68
|
else if (a === "--next") out.next = true;
|
|
44
69
|
else if (a === "--handoff") out.handoff = true;
|
|
45
70
|
else if (a === "--reason") out.reason = argv[++i];
|
|
@@ -48,30 +73,41 @@ export function parseTicketArgs(argv) {
|
|
|
48
73
|
else if (a === "--allow-placeholder") out.allowPlaceholder = true;
|
|
49
74
|
else if (a === "--compact") out.compact = true;
|
|
50
75
|
else if (a === "--status-detail") out.statusDetail = true;
|
|
76
|
+
else if (a === "--verbose") out.verbose = true;
|
|
51
77
|
else if (a === "-h" || a === "--help") out.help = true;
|
|
78
|
+
else if (a === "--session-id") out.sessionId = argv[++i];
|
|
79
|
+
else if (!a.startsWith("-")) out.ticketId = out.ticketId || a;
|
|
52
80
|
}
|
|
53
81
|
return out;
|
|
54
82
|
}
|
|
55
83
|
|
|
56
84
|
export function parseArgs(argv) {
|
|
57
|
-
const out = { cwd: process.cwd(), dryRun: false, backup: false };
|
|
85
|
+
const out: Record<string, any> = { cwd: process.cwd(), dryRun: false, backup: false };
|
|
58
86
|
for (let i = 0; i < argv.length; i++) {
|
|
59
87
|
const a = argv[i];
|
|
60
|
-
if (a === "--cwd")
|
|
88
|
+
if (a === "--cwd") {
|
|
89
|
+
out.cwd = argv[++i];
|
|
90
|
+
out.cwdExplicit = true;
|
|
91
|
+
}
|
|
61
92
|
else if (a === "--dry-run") out.dryRun = true;
|
|
62
93
|
else if (a === "--backup") out.backup = true;
|
|
63
94
|
else if (a === "--non-interactive") out.nonInteractive = true;
|
|
64
95
|
else if (a === "--interactive") out.interactive = true;
|
|
65
96
|
else if (a === "--clean") out.clean = true;
|
|
66
97
|
else if (a === "--tag") out.tag = argv[++i];
|
|
98
|
+
else if (a === "--platform") out.platform = argv[++i];
|
|
67
99
|
else if (a === "--marker-begin") out.markerBegin = argv[++i];
|
|
68
100
|
else if (a === "--marker-end") out.markerEnd = argv[++i];
|
|
69
|
-
else if (a === "--agents") out.agents = argv[++i];
|
|
70
101
|
else if (a === "--cursorrules") out.cursorrules = argv[++i];
|
|
71
102
|
else if (a === "--append-if-no-markers") out.appendIfNoMarkers = true;
|
|
72
103
|
else if (a === "--workflow") out.workflowMode = argv[++i];
|
|
73
104
|
else if (a === "--approval") out.approval = argv[++i];
|
|
105
|
+
else if (a === "--workspace") out.workspace = argv[++i];
|
|
106
|
+
else if (a === "--prompt") out.prompt = argv[++i];
|
|
107
|
+
else if (a === "--project") out.project = argv[++i];
|
|
108
|
+
else if (a === "--section") out.section = argv[++i];
|
|
74
109
|
else if (a === "--json") out.json = true;
|
|
110
|
+
else if (a === "--path-only") out.pathOnly = true;
|
|
75
111
|
else if (a === "--remote") out.remote = argv[++i];
|
|
76
112
|
else if (a === "--kind" || a === "--workspace-kind") out.workspaceKind = argv[++i];
|
|
77
113
|
else if (a === "--stack" || a === "--technical-surface") out.stack = argv[++i];
|
|
@@ -80,13 +116,14 @@ export function parseArgs(argv) {
|
|
|
80
116
|
else if (a === "--no-sync") out.sync = false;
|
|
81
117
|
else if (a === "--docs-language") out.docsLanguage = argv[++i];
|
|
82
118
|
else if (a === "--compact") out.compact = true;
|
|
119
|
+
else if (a === "--session-id") out.sessionId = argv[++i];
|
|
83
120
|
else if (a === "-h" || a === "--help") out.help = true;
|
|
84
121
|
}
|
|
85
122
|
return out;
|
|
86
123
|
}
|
|
87
124
|
|
|
88
125
|
export function parseSkillArgs(argv) {
|
|
89
|
-
const out = { cwd: process.cwd(), dryRun: false, nonInteractive: false };
|
|
126
|
+
const out: Record<string, any> = { cwd: process.cwd(), dryRun: false, nonInteractive: false };
|
|
90
127
|
for (let i = 0; i < argv.length; i++) {
|
|
91
128
|
const a = argv[i];
|
|
92
129
|
if (a === "--cwd") out.cwd = argv[++i];
|
|
@@ -100,7 +137,7 @@ export function parseSkillArgs(argv) {
|
|
|
100
137
|
}
|
|
101
138
|
|
|
102
139
|
export function parseUsageArgs(argv) {
|
|
103
|
-
const out = {
|
|
140
|
+
const out: Record<string, any> = {
|
|
104
141
|
cwd: process.cwd(),
|
|
105
142
|
json: false,
|
|
106
143
|
platform: "",
|
|
@@ -137,7 +174,7 @@ export function parseUsageArgs(argv) {
|
|
|
137
174
|
}
|
|
138
175
|
|
|
139
176
|
export function parseTelemetryArgs(argv) {
|
|
140
|
-
const out = {
|
|
177
|
+
const out: Record<string, any> = {
|
|
141
178
|
cwd: process.cwd(),
|
|
142
179
|
tokens: 0,
|
|
143
180
|
tdw: 0,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { existsSync } from "fs";
|
|
2
|
+
import { dirname, resolve } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
import { CliOpts, makePath, resolvePackageRoot } from "./cli-utils.js";
|
|
5
|
+
import { spawnSync } from "child_process";
|
|
6
|
+
|
|
7
|
+
const pkgRoot = resolvePackageRoot({ fromUrl: import.meta.url });
|
|
8
|
+
|
|
9
|
+
function contextBinCandidate() {
|
|
10
|
+
if (process.env.DEUK_AGENT_CONTEXT_BIN) {
|
|
11
|
+
return resolve(process.env.DEUK_AGENT_CONTEXT_BIN);
|
|
12
|
+
}
|
|
13
|
+
return resolve(pkgRoot, "..", "DeukAgentContext", "bin", "deuk-agent-context.js");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function runContextCommand(args = []) {
|
|
17
|
+
const localBin = contextBinCandidate();
|
|
18
|
+
const result = existsSync(localBin)
|
|
19
|
+
? spawnSync(process.execPath, [localBin, ...args], { stdio: "inherit", cwd: process.cwd() })
|
|
20
|
+
: spawnSync("deuk-agent-context", args, {
|
|
21
|
+
stdio: "inherit",
|
|
22
|
+
cwd: process.cwd(),
|
|
23
|
+
shell: process.platform === "win32",
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (result.error) {
|
|
27
|
+
if ((result.error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
28
|
+
throw new Error("deuk-agent-context command not found. Install or link DeukAgentContext, or set DEUK_AGENT_CONTEXT_BIN.");
|
|
29
|
+
}
|
|
30
|
+
throw result.error;
|
|
31
|
+
}
|
|
32
|
+
if (typeof result.status === "number" && result.status !== 0) {
|
|
33
|
+
process.exit(result.status);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { dirname } from "path";
|
|
2
|
+
import { writeFileSync, mkdirSync } from "fs";
|
|
3
|
+
import { createHash } from "crypto";
|
|
4
|
+
import { CliOpts, makePath, resolveUserHome } from "./cli-utils.js";
|
|
5
|
+
import { CLAUDE_SETTINGS_PATH, CLAUDE_USERPROMPT_SUBMIT_COMMAND, CLAUDE_USERPROMPT_SUBMIT_MATCHER, safeReadText } from "./cli-init-core.js";
|
|
6
|
+
|
|
7
|
+
function isManagedClaudePromptHookCommand(value) {
|
|
8
|
+
const command = String(value || "").trim();
|
|
9
|
+
if (!/\bdeuk-agent-flow\b/.test(command)) return false;
|
|
10
|
+
// 현재 정식 커맨드이거나, rules를 포함하는 관리형 커맨드(구버전 포함)
|
|
11
|
+
if (command === CLAUDE_USERPROMPT_SUBMIT_COMMAND) return true;
|
|
12
|
+
if (/\brules\b/.test(command)) return true;
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function isCommandHookItem(item) {
|
|
17
|
+
return Boolean(item && typeof item === "object" && item.type === "command" && typeof item.command === "string");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function readClaudeSettings(homeDir = resolveUserHome()) {
|
|
21
|
+
const settingsPath = makePath(homeDir, CLAUDE_SETTINGS_PATH);
|
|
22
|
+
const raw = safeReadText(settingsPath);
|
|
23
|
+
if (!raw.trim()) return { ok: false };
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const parsed = JSON.parse(raw);
|
|
27
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return { ok: false };
|
|
28
|
+
return { ok: true, path: settingsPath, parsed };
|
|
29
|
+
} catch {
|
|
30
|
+
return { ok: false };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function writeClaudeSettings(settingsPath, next, dryRun) {
|
|
35
|
+
if (dryRun) return;
|
|
36
|
+
mkdirSync(dirname(settingsPath), { recursive: true });
|
|
37
|
+
writeFileSync(settingsPath, `${JSON.stringify(next, null, 2)}\n`, "utf8");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function hashClaudeSettingsState(settings) {
|
|
41
|
+
return createHash("sha256").update(JSON.stringify(settings, null, 2), "utf8").digest("hex");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function upsertClaudeUserPromptSubmitHook({ homeDir = resolveUserHome(), dryRun = false } = {}) {
|
|
45
|
+
const state = readClaudeSettings(homeDir);
|
|
46
|
+
if (!state.ok) return { changed: false };
|
|
47
|
+
|
|
48
|
+
const settings = state.parsed;
|
|
49
|
+
const hooksRoot = (settings.hooks && typeof settings.hooks === "object" && !Array.isArray(settings.hooks))
|
|
50
|
+
? { ...settings.hooks }
|
|
51
|
+
: {};
|
|
52
|
+
|
|
53
|
+
const rawEntries = Array.isArray(hooksRoot.UserPromptSubmit) ? [...hooksRoot.UserPromptSubmit] : [];
|
|
54
|
+
const nextEntries = [];
|
|
55
|
+
let changed = false;
|
|
56
|
+
let hadManagedPromptSubmitHook = false;
|
|
57
|
+
let inserted = false;
|
|
58
|
+
let matcherIndex = -1;
|
|
59
|
+
|
|
60
|
+
for (const rawEntry of rawEntries) {
|
|
61
|
+
if (!rawEntry || typeof rawEntry !== "object") {
|
|
62
|
+
nextEntries.push(rawEntry);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const entry = { ...rawEntry };
|
|
67
|
+
const hooks = Array.isArray(entry.hooks) ? entry.hooks : [];
|
|
68
|
+
const keptHooks = [];
|
|
69
|
+
for (const hook of hooks) {
|
|
70
|
+
if (isCommandHookItem(hook) && isManagedClaudePromptHookCommand(hook.command)) {
|
|
71
|
+
hadManagedPromptSubmitHook = true;
|
|
72
|
+
changed = true;
|
|
73
|
+
if (!inserted) {
|
|
74
|
+
keptHooks.push({ type: "command", command: CLAUDE_USERPROMPT_SUBMIT_COMMAND });
|
|
75
|
+
inserted = true;
|
|
76
|
+
}
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
keptHooks.push(hook);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
entry.hooks = keptHooks;
|
|
83
|
+
if (entry.matcher === CLAUDE_USERPROMPT_SUBMIT_MATCHER && matcherIndex === -1) {
|
|
84
|
+
matcherIndex = nextEntries.length;
|
|
85
|
+
}
|
|
86
|
+
nextEntries.push(entry);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const hasCanonicalNow = nextEntries.some((entry) => {
|
|
90
|
+
if (!entry || typeof entry !== "object" || !Array.isArray(entry.hooks)) return false;
|
|
91
|
+
return entry.hooks.some((hook) => isCommandHookItem(hook) && hook.command === CLAUDE_USERPROMPT_SUBMIT_COMMAND);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (!hasCanonicalNow) {
|
|
95
|
+
if (nextEntries.length === 0) {
|
|
96
|
+
nextEntries.push({
|
|
97
|
+
matcher: CLAUDE_USERPROMPT_SUBMIT_MATCHER,
|
|
98
|
+
hooks: [{ type: "command", command: CLAUDE_USERPROMPT_SUBMIT_COMMAND }]
|
|
99
|
+
});
|
|
100
|
+
changed = true;
|
|
101
|
+
} else {
|
|
102
|
+
const targetIndex = matcherIndex >= 0 ? matcherIndex : 0;
|
|
103
|
+
const target = nextEntries[targetIndex];
|
|
104
|
+
const targetHooks = Array.isArray(target.hooks) ? target.hooks : [];
|
|
105
|
+
target.hooks = [...targetHooks, { type: "command", command: CLAUDE_USERPROMPT_SUBMIT_COMMAND }];
|
|
106
|
+
if (typeof target.matcher !== "string") target.matcher = CLAUDE_USERPROMPT_SUBMIT_MATCHER;
|
|
107
|
+
changed = true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const filteredEntries = nextEntries.filter((entry) => {
|
|
112
|
+
if (!entry || typeof entry !== "object") return true;
|
|
113
|
+
if (!Array.isArray(entry.hooks)) return true;
|
|
114
|
+
return entry.hooks.length > 0;
|
|
115
|
+
});
|
|
116
|
+
const finalEntries = filteredEntries.length > 0 ? filteredEntries : nextEntries;
|
|
117
|
+
|
|
118
|
+
const nextSettings = {
|
|
119
|
+
...settings,
|
|
120
|
+
hooks: {
|
|
121
|
+
...(hooksRoot),
|
|
122
|
+
UserPromptSubmit: finalEntries
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const beforeHash = hashClaudeSettingsState(settings);
|
|
127
|
+
const afterHash = hashClaudeSettingsState(nextSettings);
|
|
128
|
+
if (beforeHash === afterHash) return { changed: false, hash: beforeHash };
|
|
129
|
+
|
|
130
|
+
writeClaudeSettings(state.path, nextSettings, dryRun);
|
|
131
|
+
return { changed: true, hash: afterHash };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function removeClaudeUserPromptSubmitHook({ homeDir = resolveUserHome(), dryRun = false } = {}) {
|
|
135
|
+
const state = readClaudeSettings(homeDir);
|
|
136
|
+
if (!state.ok) return { changed: false };
|
|
137
|
+
|
|
138
|
+
const settings = state.parsed;
|
|
139
|
+
const hooksRoot = settings.hooks;
|
|
140
|
+
if (!hooksRoot || typeof hooksRoot !== "object" || Array.isArray(hooksRoot)) return { changed: false };
|
|
141
|
+
|
|
142
|
+
const current = Array.isArray(hooksRoot.UserPromptSubmit) ? hooksRoot.UserPromptSubmit : [];
|
|
143
|
+
const next = [];
|
|
144
|
+
let changed = false;
|
|
145
|
+
|
|
146
|
+
for (const entry of current) {
|
|
147
|
+
if (!entry || typeof entry !== "object") {
|
|
148
|
+
next.push(entry);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const hooks = Array.isArray(entry.hooks) ? entry.hooks : [];
|
|
152
|
+
const nextHooks = hooks.filter((hook) => !(isCommandHookItem(hook) && isManagedClaudePromptHookCommand(hook.command)));
|
|
153
|
+
if (nextHooks.length !== hooks.length) changed = true;
|
|
154
|
+
if (nextHooks.length > 0) {
|
|
155
|
+
next.push({ ...entry, hooks: nextHooks });
|
|
156
|
+
} else {
|
|
157
|
+
changed = true;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (!changed) return { changed: false };
|
|
162
|
+
|
|
163
|
+
const nextHooksRoot = { ...hooksRoot };
|
|
164
|
+
if (next.length > 0) {
|
|
165
|
+
nextHooksRoot.UserPromptSubmit = next;
|
|
166
|
+
} else {
|
|
167
|
+
delete nextHooksRoot.UserPromptSubmit;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const nextSettings = {
|
|
171
|
+
...settings,
|
|
172
|
+
hooks: nextHooksRoot
|
|
173
|
+
};
|
|
174
|
+
const beforeHash = hashClaudeSettingsState(settings);
|
|
175
|
+
const afterHash = hashClaudeSettingsState(nextSettings);
|
|
176
|
+
if (beforeHash === afterHash) return { changed: false, hash: beforeHash };
|
|
177
|
+
writeClaudeSettings(state.path, nextSettings, dryRun);
|
|
178
|
+
return { changed: true, hash: afterHash };
|
|
179
|
+
}
|