duaer-spec 0.1.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/.cursor/rules/agents-workflow.mdc +50 -0
- package/.cursor/rules/ai-ui-copy.mdc +12 -0
- package/.cursor/rules/duaer-spec.mdc +33 -0
- package/.cursor/skills/duaer-analyze/SKILL.md +259 -0
- package/.cursor/skills/duaer-checklist/SKILL.md +383 -0
- package/.cursor/skills/duaer-clarify/SKILL.md +291 -0
- package/.cursor/skills/duaer-constitution/SKILL.md +177 -0
- package/.cursor/skills/duaer-converge/SKILL.md +277 -0
- package/.cursor/skills/duaer-git-commit/SKILL.md +68 -0
- package/.cursor/skills/duaer-git-feature/SKILL.md +94 -0
- package/.cursor/skills/duaer-git-initialize/SKILL.md +54 -0
- package/.cursor/skills/duaer-git-remote/SKILL.md +50 -0
- package/.cursor/skills/duaer-git-validate/SKILL.md +54 -0
- package/.cursor/skills/duaer-implement/SKILL.md +226 -0
- package/.cursor/skills/duaer-plan/SKILL.md +166 -0
- package/.cursor/skills/duaer-specify/SKILL.md +345 -0
- package/.cursor/skills/duaer-tasks/SKILL.md +214 -0
- package/.cursor/skills/duaer-taskstoissues/SKILL.md +109 -0
- package/.duaer/extensions/.registry +23 -0
- package/.duaer/extensions/git/README.md +119 -0
- package/.duaer/extensions/git/commands/duaer.git.commit.md +63 -0
- package/.duaer/extensions/git/commands/duaer.git.feature.md +82 -0
- package/.duaer/extensions/git/commands/duaer.git.initialize.md +49 -0
- package/.duaer/extensions/git/commands/duaer.git.remote.md +45 -0
- package/.duaer/extensions/git/commands/duaer.git.validate.md +49 -0
- package/.duaer/extensions/git/config-template.yml +79 -0
- package/.duaer/extensions/git/extension.yml +142 -0
- package/.duaer/extensions/git/git-config.yml +79 -0
- package/.duaer/extensions/git/scripts/bash/auto-commit.sh +211 -0
- package/.duaer/extensions/git/scripts/bash/create-new-feature-branch.sh +626 -0
- package/.duaer/extensions/git/scripts/bash/git-common.sh +56 -0
- package/.duaer/extensions/git/scripts/bash/initialize-repo.sh +54 -0
- package/.duaer/extensions/git/scripts/powershell/auto-commit.ps1 +230 -0
- package/.duaer/extensions/git/scripts/powershell/create-new-feature-branch.ps1 +592 -0
- package/.duaer/extensions/git/scripts/powershell/git-common.ps1 +52 -0
- package/.duaer/extensions/git/scripts/powershell/initialize-repo.ps1 +69 -0
- package/.duaer/extensions/git/scripts/python/auto_commit.py +195 -0
- package/.duaer/extensions/git/scripts/python/create_new_feature_branch.py +634 -0
- package/.duaer/extensions/git/scripts/python/git_common.py +81 -0
- package/.duaer/extensions/git/scripts/python/initialize_repo.py +89 -0
- package/.duaer/extensions.yml +167 -0
- package/.duaer/init-options.json +9 -0
- package/.duaer/integration.json +15 -0
- package/.duaer/integrations/cursor-agent.manifest.json +17 -0
- package/.duaer/integrations/duaer.manifest.json +19 -0
- package/.duaer/memory/.constitution-template.json +4 -0
- package/.duaer/memory/constitution.md +37 -0
- package/.duaer/memory/project-context.md +24 -0
- package/.duaer/memory/testing.md +14 -0
- package/.duaer/scripts/bash/check-prerequisites.sh +243 -0
- package/.duaer/scripts/bash/common.sh +926 -0
- package/.duaer/scripts/bash/create-new-feature.sh +407 -0
- package/.duaer/scripts/bash/resolve-template.sh +57 -0
- package/.duaer/scripts/bash/setup-plan.sh +85 -0
- package/.duaer/scripts/bash/setup-tasks.sh +94 -0
- package/.duaer/templates/checklist-template.md +45 -0
- package/.duaer/templates/constitution-template.md +50 -0
- package/.duaer/templates/plan-template.md +113 -0
- package/.duaer/templates/spec-template.md +131 -0
- package/.duaer/templates/tasks-template.md +252 -0
- package/.duaer/workflows/duaer/workflow.yml +78 -0
- package/.duaer/workflows/workflow-registry.json +13 -0
- package/ADOPT.md +75 -0
- package/AGENTS.md +290 -0
- package/CHANGELOG.md +28 -0
- package/DUADER.md +57 -0
- package/LICENSE +21 -0
- package/README.md +74 -0
- package/bin/duaer.mjs +298 -0
- package/docs/agent/README.md +12 -0
- package/docs/agent/change-checklist.md +130 -0
- package/docs/agent/e2e-test-plan.md +33 -0
- package/docs/agent/workflow.md +127 -0
- package/docs/baseline.md +10 -0
- package/package.json +49 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Git-specific common helpers for the git extension.
|
|
3
|
+
|
|
4
|
+
Python port of ``git-common.sh`` / ``git-common.ps1`` — contains only
|
|
5
|
+
git-specific branch validation and detection logic.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import re
|
|
11
|
+
import shutil
|
|
12
|
+
import subprocess
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def has_git(repo_root: Path | None = None) -> bool:
|
|
18
|
+
"""Check if we have git available at the repo root."""
|
|
19
|
+
root = Path(repo_root) if repo_root is not None else Path.cwd()
|
|
20
|
+
git_marker = root / ".git"
|
|
21
|
+
if not (git_marker.is_dir() or git_marker.is_file()):
|
|
22
|
+
return False
|
|
23
|
+
if shutil.which("git") is None:
|
|
24
|
+
return False
|
|
25
|
+
result = subprocess.run(
|
|
26
|
+
["git", "-C", str(root), "rev-parse", "--is-inside-work-tree"],
|
|
27
|
+
capture_output=True,
|
|
28
|
+
text=True,
|
|
29
|
+
)
|
|
30
|
+
return result.returncode == 0
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def effective_branch_name(raw: str) -> str:
|
|
34
|
+
"""Strip a single optional path segment (e.g. gitflow "feat/004-name" -> "004-name").
|
|
35
|
+
|
|
36
|
+
Only when the full name is exactly two slash-free segments; otherwise
|
|
37
|
+
returns the raw name.
|
|
38
|
+
"""
|
|
39
|
+
match = re.fullmatch(r"([^/]+)/([^/]+)", raw)
|
|
40
|
+
if match:
|
|
41
|
+
return match.group(2)
|
|
42
|
+
return raw
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def check_feature_branch(raw: str, has_git_repo: bool) -> bool:
|
|
46
|
+
"""Validate that a branch name matches the expected feature branch pattern.
|
|
47
|
+
|
|
48
|
+
Accepts sequential (###-* with >=3 digits) or timestamp (YYYYMMDD-HHMMSS-*)
|
|
49
|
+
formats, either at the start of the branch or after path-style namespace
|
|
50
|
+
prefixes. Logic aligned with the bash/PowerShell twins.
|
|
51
|
+
"""
|
|
52
|
+
if not has_git_repo:
|
|
53
|
+
print(
|
|
54
|
+
"[specify] Warning: Git repository not detected; skipped branch validation",
|
|
55
|
+
file=sys.stderr,
|
|
56
|
+
)
|
|
57
|
+
return True
|
|
58
|
+
|
|
59
|
+
branch = effective_branch_name(raw)
|
|
60
|
+
feature_segment = branch.rsplit("/", 1)[-1]
|
|
61
|
+
|
|
62
|
+
# Accept sequential prefix (3+ digits) but exclude malformed timestamps:
|
|
63
|
+
# 7-or-8 digit date + 6-digit time with no trailing slug.
|
|
64
|
+
is_sequential = bool(
|
|
65
|
+
re.match(r"^[0-9]{3,}-", feature_segment)
|
|
66
|
+
and not re.match(r"^[0-9]{7}-[0-9]{6}-", feature_segment)
|
|
67
|
+
and not re.fullmatch(r"[0-9]{7,8}-[0-9]{6}", feature_segment)
|
|
68
|
+
)
|
|
69
|
+
is_timestamp = bool(re.match(r"^[0-9]{8}-[0-9]{6}-", feature_segment))
|
|
70
|
+
|
|
71
|
+
if not is_sequential and not is_timestamp:
|
|
72
|
+
print(f"ERROR: Not on a feature branch. Current branch: {raw}", file=sys.stderr)
|
|
73
|
+
print(
|
|
74
|
+
"Feature branches should be named like: 001-feature-name, "
|
|
75
|
+
"1234-feature-name, 20260319-143022-feature-name, or "
|
|
76
|
+
"<prefix>/001-feature-name",
|
|
77
|
+
file=sys.stderr,
|
|
78
|
+
)
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
return True
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Git extension: initialize_repo.py
|
|
3
|
+
|
|
4
|
+
Initialize a Git repository with an initial commit.
|
|
5
|
+
Python port of ``initialize-repo.sh`` / ``initialize-repo.ps1``.
|
|
6
|
+
Customizable — replace this script to add .gitignore templates,
|
|
7
|
+
default branch config, git-flow, LFS, signing, etc.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import re
|
|
13
|
+
import shutil
|
|
14
|
+
import subprocess
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _find_project_root(start: Path) -> Path | None:
|
|
20
|
+
current = start
|
|
21
|
+
while True:
|
|
22
|
+
if (current / ".duaer").is_dir() or (current / ".git").exists():
|
|
23
|
+
return current
|
|
24
|
+
if current.parent == current:
|
|
25
|
+
return None
|
|
26
|
+
current = current.parent
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _read_commit_message(repo_root: Path) -> str:
|
|
30
|
+
"""Read init_commit_message from git-config.yml, mirroring the bash sed pipeline."""
|
|
31
|
+
default = "[Duaer] Initial commit"
|
|
32
|
+
config_file = repo_root / ".duaer" / "extensions" / "git" / "git-config.yml"
|
|
33
|
+
if not config_file.is_file():
|
|
34
|
+
return default
|
|
35
|
+
try:
|
|
36
|
+
lines = config_file.read_text(encoding="utf-8").splitlines()
|
|
37
|
+
except (OSError, UnicodeDecodeError):
|
|
38
|
+
return default
|
|
39
|
+
for line in lines:
|
|
40
|
+
if line.startswith("init_commit_message:"):
|
|
41
|
+
value = re.sub(r"^init_commit_message:\s*", "", line)
|
|
42
|
+
value = re.sub(r"^[\"']", "", value)
|
|
43
|
+
value = re.sub(r"[\"']*$", "", value)
|
|
44
|
+
if value:
|
|
45
|
+
return value
|
|
46
|
+
return default
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def main() -> int:
|
|
50
|
+
script_dir = Path(__file__).resolve().parent
|
|
51
|
+
repo_root = _find_project_root(script_dir) or Path.cwd()
|
|
52
|
+
|
|
53
|
+
commit_msg = _read_commit_message(repo_root)
|
|
54
|
+
|
|
55
|
+
if shutil.which("git") is None:
|
|
56
|
+
print(
|
|
57
|
+
"[specify] Warning: Git not found; skipped repository initialization",
|
|
58
|
+
file=sys.stderr,
|
|
59
|
+
)
|
|
60
|
+
return 0
|
|
61
|
+
|
|
62
|
+
probe = subprocess.run(
|
|
63
|
+
["git", "rev-parse", "--is-inside-work-tree"],
|
|
64
|
+
cwd=repo_root,
|
|
65
|
+
capture_output=True,
|
|
66
|
+
text=True,
|
|
67
|
+
)
|
|
68
|
+
if probe.returncode == 0:
|
|
69
|
+
print("[specify] Git repository already initialized; skipping", file=sys.stderr)
|
|
70
|
+
return 0
|
|
71
|
+
|
|
72
|
+
steps = [
|
|
73
|
+
(["git", "init", "-q"], "git init"),
|
|
74
|
+
(["git", "add", "."], "git add"),
|
|
75
|
+
(["git", "commit", "--allow-empty", "-q", "-m", commit_msg], "git commit"),
|
|
76
|
+
]
|
|
77
|
+
for cmd, label in steps:
|
|
78
|
+
result = subprocess.run(cmd, cwd=repo_root, capture_output=True, text=True)
|
|
79
|
+
if result.returncode != 0:
|
|
80
|
+
output = (result.stdout + result.stderr).strip()
|
|
81
|
+
print(f"[specify] Error: {label} failed: {output}", file=sys.stderr)
|
|
82
|
+
return 1
|
|
83
|
+
|
|
84
|
+
print("[OK] Git repository initialized", file=sys.stderr)
|
|
85
|
+
return 0
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
installed:
|
|
2
|
+
- git
|
|
3
|
+
settings:
|
|
4
|
+
auto_execute_hooks: true
|
|
5
|
+
hooks:
|
|
6
|
+
before_constitution:
|
|
7
|
+
- extension: git
|
|
8
|
+
command: duaer.git.initialize
|
|
9
|
+
enabled: true
|
|
10
|
+
optional: false
|
|
11
|
+
priority: 10
|
|
12
|
+
prompt: Execute duaer.git.initialize?
|
|
13
|
+
description: Initialize Git repository before constitution setup
|
|
14
|
+
condition: null
|
|
15
|
+
before_specify:
|
|
16
|
+
- extension: git
|
|
17
|
+
command: duaer.git.feature
|
|
18
|
+
enabled: true
|
|
19
|
+
optional: false
|
|
20
|
+
priority: 10
|
|
21
|
+
prompt: Execute duaer.git.feature?
|
|
22
|
+
description: Create feature branch before specification
|
|
23
|
+
condition: null
|
|
24
|
+
before_clarify:
|
|
25
|
+
- extension: git
|
|
26
|
+
command: duaer.git.commit
|
|
27
|
+
enabled: true
|
|
28
|
+
optional: true
|
|
29
|
+
priority: 10
|
|
30
|
+
prompt: Commit outstanding changes before clarification?
|
|
31
|
+
description: Auto-commit before spec clarification
|
|
32
|
+
condition: null
|
|
33
|
+
before_plan:
|
|
34
|
+
- extension: git
|
|
35
|
+
command: duaer.git.commit
|
|
36
|
+
enabled: true
|
|
37
|
+
optional: true
|
|
38
|
+
priority: 10
|
|
39
|
+
prompt: Commit outstanding changes before planning?
|
|
40
|
+
description: Auto-commit before implementation planning
|
|
41
|
+
condition: null
|
|
42
|
+
before_tasks:
|
|
43
|
+
- extension: git
|
|
44
|
+
command: duaer.git.commit
|
|
45
|
+
enabled: true
|
|
46
|
+
optional: true
|
|
47
|
+
priority: 10
|
|
48
|
+
prompt: Commit outstanding changes before task generation?
|
|
49
|
+
description: Auto-commit before task generation
|
|
50
|
+
condition: null
|
|
51
|
+
before_implement:
|
|
52
|
+
- extension: git
|
|
53
|
+
command: duaer.git.commit
|
|
54
|
+
enabled: true
|
|
55
|
+
optional: true
|
|
56
|
+
priority: 10
|
|
57
|
+
prompt: Commit outstanding changes before implementation?
|
|
58
|
+
description: Auto-commit before implementation
|
|
59
|
+
condition: null
|
|
60
|
+
before_checklist:
|
|
61
|
+
- extension: git
|
|
62
|
+
command: duaer.git.commit
|
|
63
|
+
enabled: true
|
|
64
|
+
optional: true
|
|
65
|
+
priority: 10
|
|
66
|
+
prompt: Commit outstanding changes before checklist?
|
|
67
|
+
description: Auto-commit before checklist generation
|
|
68
|
+
condition: null
|
|
69
|
+
before_analyze:
|
|
70
|
+
- extension: git
|
|
71
|
+
command: duaer.git.commit
|
|
72
|
+
enabled: true
|
|
73
|
+
optional: true
|
|
74
|
+
priority: 10
|
|
75
|
+
prompt: Commit outstanding changes before analysis?
|
|
76
|
+
description: Auto-commit before analysis
|
|
77
|
+
condition: null
|
|
78
|
+
before_taskstoissues:
|
|
79
|
+
- extension: git
|
|
80
|
+
command: duaer.git.commit
|
|
81
|
+
enabled: true
|
|
82
|
+
optional: true
|
|
83
|
+
priority: 10
|
|
84
|
+
prompt: Commit outstanding changes before issue sync?
|
|
85
|
+
description: Auto-commit before tasks-to-issues conversion
|
|
86
|
+
condition: null
|
|
87
|
+
after_constitution:
|
|
88
|
+
- extension: git
|
|
89
|
+
command: duaer.git.commit
|
|
90
|
+
enabled: true
|
|
91
|
+
optional: true
|
|
92
|
+
priority: 10
|
|
93
|
+
prompt: Commit constitution changes?
|
|
94
|
+
description: Auto-commit after constitution update
|
|
95
|
+
condition: null
|
|
96
|
+
after_specify:
|
|
97
|
+
- extension: git
|
|
98
|
+
command: duaer.git.commit
|
|
99
|
+
enabled: true
|
|
100
|
+
optional: true
|
|
101
|
+
priority: 10
|
|
102
|
+
prompt: Commit specification changes?
|
|
103
|
+
description: Auto-commit after specification
|
|
104
|
+
condition: null
|
|
105
|
+
after_clarify:
|
|
106
|
+
- extension: git
|
|
107
|
+
command: duaer.git.commit
|
|
108
|
+
enabled: true
|
|
109
|
+
optional: true
|
|
110
|
+
priority: 10
|
|
111
|
+
prompt: Commit clarification changes?
|
|
112
|
+
description: Auto-commit after spec clarification
|
|
113
|
+
condition: null
|
|
114
|
+
after_plan:
|
|
115
|
+
- extension: git
|
|
116
|
+
command: duaer.git.commit
|
|
117
|
+
enabled: true
|
|
118
|
+
optional: true
|
|
119
|
+
priority: 10
|
|
120
|
+
prompt: Commit plan changes?
|
|
121
|
+
description: Auto-commit after implementation planning
|
|
122
|
+
condition: null
|
|
123
|
+
after_tasks:
|
|
124
|
+
- extension: git
|
|
125
|
+
command: duaer.git.commit
|
|
126
|
+
enabled: true
|
|
127
|
+
optional: true
|
|
128
|
+
priority: 10
|
|
129
|
+
prompt: Commit task changes?
|
|
130
|
+
description: Auto-commit after task generation
|
|
131
|
+
condition: null
|
|
132
|
+
after_implement:
|
|
133
|
+
- extension: git
|
|
134
|
+
command: duaer.git.commit
|
|
135
|
+
enabled: true
|
|
136
|
+
optional: true
|
|
137
|
+
priority: 10
|
|
138
|
+
prompt: Commit implementation changes?
|
|
139
|
+
description: Auto-commit after implementation
|
|
140
|
+
condition: null
|
|
141
|
+
after_checklist:
|
|
142
|
+
- extension: git
|
|
143
|
+
command: duaer.git.commit
|
|
144
|
+
enabled: true
|
|
145
|
+
optional: true
|
|
146
|
+
priority: 10
|
|
147
|
+
prompt: Commit checklist changes?
|
|
148
|
+
description: Auto-commit after checklist generation
|
|
149
|
+
condition: null
|
|
150
|
+
after_analyze:
|
|
151
|
+
- extension: git
|
|
152
|
+
command: duaer.git.commit
|
|
153
|
+
enabled: true
|
|
154
|
+
optional: true
|
|
155
|
+
priority: 10
|
|
156
|
+
prompt: Commit analysis results?
|
|
157
|
+
description: Auto-commit after analysis
|
|
158
|
+
condition: null
|
|
159
|
+
after_taskstoissues:
|
|
160
|
+
- extension: git
|
|
161
|
+
command: duaer.git.commit
|
|
162
|
+
enabled: true
|
|
163
|
+
optional: true
|
|
164
|
+
priority: 10
|
|
165
|
+
prompt: Commit after syncing issues?
|
|
166
|
+
description: Auto-commit after tasks-to-issues conversion
|
|
167
|
+
condition: null
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.4",
|
|
3
|
+
"integration_state_schema": 1,
|
|
4
|
+
"installed_integrations": [
|
|
5
|
+
"cursor-agent"
|
|
6
|
+
],
|
|
7
|
+
"integration_settings": {
|
|
8
|
+
"cursor-agent": {
|
|
9
|
+
"script": "sh",
|
|
10
|
+
"invoke_separator": "-"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"integration": "cursor-agent",
|
|
14
|
+
"default_integration": "cursor-agent"
|
|
15
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"integration": "cursor-agent",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"installed_at": "2026-09-03T21:13:31.261739+00:00",
|
|
5
|
+
"files": {
|
|
6
|
+
".cursor/skills/duaer-analyze/SKILL.md": "7deb401f0e53be0264722db1c2d401b279ca64ad3fc886a186de39f7ffd5be42",
|
|
7
|
+
".cursor/skills/duaer-clarify/SKILL.md": "e1a1ddba9346721f41e7b8d0ad278b54d69399c0625db9d753756fd33e51a6e1",
|
|
8
|
+
".cursor/skills/duaer-constitution/SKILL.md": "442e1c84f9a9f2267700cf08157b2aff65e00abae687689f639ce8f62ff8b6f5",
|
|
9
|
+
".cursor/skills/duaer-implement/SKILL.md": "df979ca34543fbde2336626752ef72020aa68f4b38c2d108a2da4473113977db",
|
|
10
|
+
".cursor/skills/duaer-converge/SKILL.md": "aca98c2c55ba124dbddc467642dc90c673f7657ff750b9a93d89916058dded0d",
|
|
11
|
+
".cursor/skills/duaer-plan/SKILL.md": "3d13e010accc60766db3549a52f598e643f5f6c26570a475df418c7a74ba4cbb",
|
|
12
|
+
".cursor/skills/duaer-checklist/SKILL.md": "057a2bd2cc91184a6a0b3b2e0fcf6704d4ef55cc1c5939b40e1968431ee10061",
|
|
13
|
+
".cursor/skills/duaer-specify/SKILL.md": "d0b83970b14be40bd1dcd5d3c15f3186c37ebebbe4617dda7e8d487763b70f79",
|
|
14
|
+
".cursor/skills/duaer-tasks/SKILL.md": "24e873a5a7adb75e832b6100d6c9140b0a0df4b9650ba32b8102e37697332beb",
|
|
15
|
+
".cursor/skills/duaer-taskstoissues/SKILL.md": "225297f98e77807dd261ea5692ca0a5b286902d7c9b4855fc30b93f4283ce0a6"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"integration": "duaer",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"installed_at": "2026-09-03T21:13:31.277502+00:00",
|
|
5
|
+
"files": {
|
|
6
|
+
".duaer/scripts/bash/common.sh": "170e91ece502b88d83c715e427473843e0b358f550e86e3ff524546df405a9ca",
|
|
7
|
+
".duaer/scripts/bash/setup-plan.sh": "f417e1b8de7a48fa9d5fea3aabea8fe62149fa11c4b41b3103de06efe73dec8d",
|
|
8
|
+
".duaer/scripts/bash/setup-tasks.sh": "4a33dd1e6c32ddc7d570f4b538572c54069192573eed0ec654d9fb826e31a4fe",
|
|
9
|
+
".duaer/scripts/bash/check-prerequisites.sh": "daa377146db4fb69912f42611a7b91c5d55873b3e3e27ed33bd8d67505826344",
|
|
10
|
+
".duaer/scripts/bash/resolve-template.sh": "829e227096abc8bf0889889ec9f792f503ca5d395b7836a8a7eb739ee75214e7",
|
|
11
|
+
".duaer/scripts/bash/create-new-feature.sh": "fe99ea8da184380056ce8512ca5d37f67fb499ee4234835c15dcf7c4fb75451c",
|
|
12
|
+
".duaer/templates/constitution-template.md": "ce7549540fa45543cca797a150201d868e64495fdff39dc38246fb17bd4024b3",
|
|
13
|
+
".duaer/templates/checklist-template.md": "856532b3cb66171c662cc16f16b31a5856e4655a8666aad1e545bbfc7f603ca1",
|
|
14
|
+
".duaer/templates/tasks-template.md": "fc29a233f6f5a27ca31f1aa46b596af6500c627441c6e62b2bc4a1d721525842",
|
|
15
|
+
".duaer/templates/spec-template.md": "3945437fc35cd30a5b2bf7beea680337c3516826d3efa5a6b92c4a7eca1ba28e",
|
|
16
|
+
".duaer/templates/plan-template.md": "7e637502d41eccf0ca672496636365691fdca62ef37b27ec07fcb412dbfa90d4",
|
|
17
|
+
".duaer/.gitignore": "8c908410d177a1ef3d0dee16d7ad55f2ac3333df3104c4d4adee1c9b82f1dbc1"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Project Constitution (template)
|
|
2
|
+
|
|
3
|
+
Replace this file per project. Keep it short and enforceable.
|
|
4
|
+
|
|
5
|
+
Part of **duaer-spec**. If the host repo's `AGENTS.md` conflicts with this
|
|
6
|
+
constitution on isolation, commits, or Issue/PR gates, follow `AGENTS.md`; keep
|
|
7
|
+
Duaer for what to build.
|
|
8
|
+
|
|
9
|
+
## Core Principles
|
|
10
|
+
|
|
11
|
+
### I. Spec before code (NON-NEGOTIABLE)
|
|
12
|
+
|
|
13
|
+
Features, architecture changes, and hotfixes start with a Duaer feature
|
|
14
|
+
artifact before implementation. Default path:
|
|
15
|
+
|
|
16
|
+
`constitution` → `specify` → (optional `clarify`) → `plan` → (optional `checklist` / `analyze`) → `tasks` → `implement` → `converge`
|
|
17
|
+
|
|
18
|
+
Hotfix may shorten to: `specify` (mark hotfix) → `tasks` → `implement` → `converge`.
|
|
19
|
+
Never skip `specify` or `converge`.
|
|
20
|
+
|
|
21
|
+
### II. Read as-is before changing
|
|
22
|
+
|
|
23
|
+
Before any feature work, read:
|
|
24
|
+
|
|
25
|
+
1. This constitution
|
|
26
|
+
2. `.duaer/memory/project-context.md` (implementation truth)
|
|
27
|
+
3. Project product intent doc (if any)
|
|
28
|
+
|
|
29
|
+
### III. Smallest coherent change
|
|
30
|
+
|
|
31
|
+
Prefer the smallest change that satisfies the acceptance criteria in `spec.md`.
|
|
32
|
+
Do not expand scope without updating the spec and tasks.
|
|
33
|
+
|
|
34
|
+
### IV. Verify before done
|
|
35
|
+
|
|
36
|
+
Mark tasks complete only when the stated verification (tests, manual checks,
|
|
37
|
+
or converge) has been performed or explicitly waived in the feature docs.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Project context (as-is)
|
|
2
|
+
|
|
3
|
+
Fill this in for each project. Agents treat it as implementation truth.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- Language / runtime:
|
|
8
|
+
- Package manager:
|
|
9
|
+
- App entrypoints:
|
|
10
|
+
- Test commands:
|
|
11
|
+
|
|
12
|
+
## Layout
|
|
13
|
+
|
|
14
|
+
- Source roots:
|
|
15
|
+
- Important packages / apps:
|
|
16
|
+
|
|
17
|
+
## Non-negotiable boundaries
|
|
18
|
+
|
|
19
|
+
- Do not:
|
|
20
|
+
- Always:
|
|
21
|
+
|
|
22
|
+
## Known gotchas
|
|
23
|
+
|
|
24
|
+
-
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Testing expectations (template)
|
|
2
|
+
|
|
3
|
+
## Levels
|
|
4
|
+
|
|
5
|
+
- L0: lint / typecheck
|
|
6
|
+
- L1: unit tests for changed modules
|
|
7
|
+
- L2: integration tests for changed boundaries
|
|
8
|
+
- L3: e2e / browser for user-visible paths
|
|
9
|
+
- L4: manual account verification when UI or auth is involved
|
|
10
|
+
|
|
11
|
+
## Default for features
|
|
12
|
+
|
|
13
|
+
Specs and `tasks.md` must include verification tasks. Prefer automated checks;
|
|
14
|
+
document any manual step that cannot be automated.
|