@deftai/directive-content 0.55.1 → 0.56.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/.githooks/pre-commit +143 -0
- package/.githooks/pre-push +121 -0
- package/QUICK-START.md +13 -3
- package/Taskfile.yml +934 -0
- package/UPGRADING.md +82 -11
- package/events/README.md +3 -3
- package/package.json +5 -4
- package/packs/skills/skills-pack-0.1.json +22 -22
- package/scripts/_agents_md.py +494 -0
- package/scripts/_cache_fetch.py +635 -0
- package/scripts/_cache_quota.py +529 -0
- package/scripts/_cache_refresh.py +163 -0
- package/scripts/_cache_validate.py +209 -0
- package/scripts/_content_root.py +42 -0
- package/scripts/_doctor_state.py +277 -0
- package/scripts/_event_detect.py +305 -0
- package/scripts/_events.py +514 -0
- package/scripts/_lifecycle_hygiene.py +568 -0
- package/scripts/_pathspec.py +91 -0
- package/scripts/_policy_show_cli.py +266 -0
- package/scripts/_precutover.py +92 -0
- package/scripts/_project_context.py +224 -0
- package/scripts/_project_definition_io.py +164 -0
- package/scripts/_relocate_snapshot.py +209 -0
- package/scripts/_relocate_states.py +343 -0
- package/scripts/_resolve_preflight_path.py +152 -0
- package/scripts/_safe_subprocess.py +167 -0
- package/scripts/_session_start_hook.py +205 -0
- package/scripts/_sor_gate_diff.py +365 -0
- package/scripts/_stdio_utf8.py +59 -0
- package/scripts/_triage_bootstrap_gitignore.py +904 -0
- package/scripts/_triage_classify_cli.py +122 -0
- package/scripts/_triage_queue_cli.py +625 -0
- package/scripts/_triage_scope_cli.py +343 -0
- package/scripts/_triage_scope_drift_cli.py +121 -0
- package/scripts/_triage_scope_ignores.py +286 -0
- package/scripts/_triage_scope_milestone.py +432 -0
- package/scripts/_triage_scope_mutations.py +337 -0
- package/scripts/_triage_scope_renderers.py +207 -0
- package/scripts/_triage_smoketest_stages.py +674 -0
- package/scripts/_triage_subscribe_cli.py +140 -0
- package/scripts/_triage_welcome_cli.py +421 -0
- package/scripts/_vbrief_build.py +239 -0
- package/scripts/_vbrief_fidelity.py +479 -0
- package/scripts/_vbrief_legacy.py +589 -0
- package/scripts/_vbrief_reconciliation.py +883 -0
- package/scripts/_vbrief_routing.py +277 -0
- package/scripts/_vbrief_safety.py +778 -0
- package/scripts/_vbrief_sources.py +312 -0
- package/scripts/_vbrief_speckit.py +262 -0
- package/scripts/_vbrief_story_quality.py +353 -0
- package/scripts/_vbrief_validation.py +299 -0
- package/scripts/build_dist.py +412 -0
- package/scripts/cache.py +1078 -0
- package/scripts/cache_scanner.py +745 -0
- package/scripts/candidates_log.py +432 -0
- package/scripts/capacity_backfill.py +680 -0
- package/scripts/capacity_show.py +653 -0
- package/scripts/ci_local.py +689 -0
- package/scripts/code_structure_validate.py +765 -0
- package/scripts/codebase_default_extractor.py +495 -0
- package/scripts/codebase_map.py +304 -0
- package/scripts/codebase_map_fresh.py +104 -0
- package/scripts/codebase_projection_registry.py +94 -0
- package/scripts/codebase_provider.py +582 -0
- package/scripts/doctor.py +2257 -0
- package/scripts/framework_commands.py +505 -0
- package/scripts/gh_rest.py +882 -0
- package/scripts/github_auth_modes.py +437 -0
- package/scripts/github_body.py +292 -0
- package/scripts/ip_risk.py +531 -0
- package/scripts/issue_emit.py +670 -0
- package/scripts/issue_ingest.py +1064 -0
- package/scripts/migrate_preflight.py +418 -0
- package/scripts/migrate_vbrief.py +2677 -0
- package/scripts/monitor_pr.py +401 -0
- package/scripts/pack_migrate_lessons.py +336 -0
- package/scripts/pack_migrate_patterns.py +254 -0
- package/scripts/pack_migrate_rules.py +350 -0
- package/scripts/pack_migrate_skills.py +423 -0
- package/scripts/pack_migrate_strategies.py +311 -0
- package/scripts/pack_migrate_swarm_spec.py +250 -0
- package/scripts/pack_render.py +434 -0
- package/scripts/packs_slice.py +712 -0
- package/scripts/platform_capabilities.py +336 -0
- package/scripts/policy.py +2826 -0
- package/scripts/policy_set.py +324 -0
- package/scripts/pr_check_closing_keywords.py +524 -0
- package/scripts/pr_check_protected_issues.py +267 -0
- package/scripts/pr_merge_readiness.py +1004 -0
- package/scripts/pr_wait_mergeable.py +669 -0
- package/scripts/prd_render.py +159 -0
- package/scripts/preflight_architecture_sor.py +974 -0
- package/scripts/preflight_branch.py +289 -0
- package/scripts/preflight_cache.py +974 -0
- package/scripts/preflight_gh.py +721 -0
- package/scripts/preflight_implementation.py +272 -0
- package/scripts/preflight_story_start.py +838 -0
- package/scripts/preflight_wip_cap.py +149 -0
- package/scripts/probe_session.py +545 -0
- package/scripts/project_render.py +293 -0
- package/scripts/quarantine_ext.py +237 -0
- package/scripts/reconcile_issues.py +1442 -0
- package/scripts/refresh-path.ps1 +107 -0
- package/scripts/release.py +2030 -0
- package/scripts/release_e2e.py +1011 -0
- package/scripts/release_publish.py +486 -0
- package/scripts/release_rollback.py +980 -0
- package/scripts/relocate.py +1034 -0
- package/scripts/resolve_changelog_unreleased.py +667 -0
- package/scripts/resolve_version.py +490 -0
- package/scripts/resume_conditions.py +706 -0
- package/scripts/ritual_sentinel.py +609 -0
- package/scripts/roadmap_render.py +635 -0
- package/scripts/rule_ownership_lint.py +325 -0
- package/scripts/scm.py +591 -0
- package/scripts/scope_audit_log.py +387 -0
- package/scripts/scope_decompose.py +654 -0
- package/scripts/scope_demote.py +509 -0
- package/scripts/scope_lifecycle.py +1126 -0
- package/scripts/scope_undo.py +772 -0
- package/scripts/session_start.py +406 -0
- package/scripts/setup_ghx.py +339 -0
- package/scripts/setup_windows.ps1 +220 -0
- package/scripts/slice_audit.py +585 -0
- package/scripts/slice_record.py +530 -0
- package/scripts/slice_record_existing.py +692 -0
- package/scripts/slug_normalize.py +178 -0
- package/scripts/spec_render.py +477 -0
- package/scripts/spec_validate.py +238 -0
- package/scripts/subagent_monitor.py +658 -0
- package/scripts/swarm_complete_cohort.py +644 -0
- package/scripts/swarm_launch.py +1206 -0
- package/scripts/swarm_readiness.py +554 -0
- package/scripts/swarm_verify_review_clean.py +438 -0
- package/scripts/swarm_worktrees.py +497 -0
- package/scripts/toolchain-check.py +52 -0
- package/scripts/triage_actions.py +871 -0
- package/scripts/triage_bootstrap.py +1153 -0
- package/scripts/triage_bulk.py +630 -0
- package/scripts/triage_classify.py +932 -0
- package/scripts/triage_help.py +1685 -0
- package/scripts/triage_queue.py +1944 -0
- package/scripts/triage_reconcile.py +581 -0
- package/scripts/triage_refresh.py +643 -0
- package/scripts/triage_scope.py +999 -0
- package/scripts/triage_scope_drift.py +575 -0
- package/scripts/triage_smoketest.py +396 -0
- package/scripts/triage_subscribe.py +399 -0
- package/scripts/triage_summary.py +1011 -0
- package/scripts/triage_welcome.py +1178 -0
- package/scripts/ts_check_lane.py +86 -0
- package/scripts/validate-links.py +64 -0
- package/scripts/validate_strategy_output.py +212 -0
- package/scripts/vbrief_activate.py +228 -0
- package/scripts/vbrief_migrate_conformance.py +368 -0
- package/scripts/vbrief_reconcile_graph.py +306 -0
- package/scripts/vbrief_reconcile_labels.py +460 -0
- package/scripts/vbrief_reconcile_umbrellas.py +741 -0
- package/scripts/vbrief_validate.py +1195 -0
- package/scripts/verify-stubs.py +61 -0
- package/scripts/verify_capacity.py +160 -0
- package/scripts/verify_encoding.py +699 -0
- package/scripts/verify_hooks_installed.py +206 -0
- package/scripts/verify_investigation.py +360 -0
- package/scripts/verify_judgment_gates.py +827 -0
- package/scripts/verify_no_task_runtime.py +171 -0
- package/scripts/verify_scm_boundary.py +509 -0
- package/scripts/verify_session_ritual.py +389 -0
- package/scripts/verify_tools.py +426 -0
- package/scripts/verify_vbrief_conformance.py +478 -0
- package/skills/deft-directive-swarm/SKILL.md +7 -26
- package/skills/deft-directive-sync/SKILL.md +1 -1
- package/tasks/architecture.yml +13 -0
- package/tasks/cache.yml +69 -0
- package/tasks/capacity.yml +38 -0
- package/tasks/change.yml +46 -0
- package/tasks/changelog.yml +24 -0
- package/tasks/ci.yml +49 -0
- package/tasks/codebase.yml +47 -0
- package/tasks/commit.yml +30 -0
- package/tasks/core.yml +126 -0
- package/tasks/deployments.yml +54 -0
- package/tasks/framework.yml +74 -0
- package/tasks/install.yml +60 -0
- package/tasks/issue.yml +50 -0
- package/tasks/migrate.yml +73 -0
- package/tasks/packs.yml +92 -0
- package/tasks/policy.yml +75 -0
- package/tasks/pr.yml +89 -0
- package/tasks/prd.yml +39 -0
- package/tasks/project.yml +27 -0
- package/tasks/reconcile.yml +32 -0
- package/tasks/relocate.yml +56 -0
- package/tasks/roadmap.yml +28 -0
- package/tasks/scm.yml +126 -0
- package/tasks/scope-undo.yml +36 -0
- package/tasks/scope.yml +141 -0
- package/tasks/session.yml +19 -0
- package/tasks/setup.yml +37 -0
- package/tasks/slice.yml +69 -0
- package/tasks/spec.yml +41 -0
- package/tasks/swarm.yml +85 -0
- package/tasks/toolchain.yml +13 -0
- package/tasks/triage-actions.yml +94 -0
- package/tasks/triage-bootstrap.yml +43 -0
- package/tasks/triage-bulk.yml +75 -0
- package/tasks/triage-classify.yml +30 -0
- package/tasks/triage-queue.yml +50 -0
- package/tasks/triage-reconcile.yml +29 -0
- package/tasks/triage-scope-drift.yml +29 -0
- package/tasks/triage-scope.yml +31 -0
- package/tasks/triage-smoketest.yml +33 -0
- package/tasks/triage-subscribe.yml +36 -0
- package/tasks/triage-summary.yml +29 -0
- package/tasks/triage-welcome.yml +32 -0
- package/tasks/ts.yml +328 -0
- package/tasks/vbrief.yml +206 -0
- package/tasks/verify.yml +292 -0
- package/templates/agents-entry.md +2 -2
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
vars:
|
|
4
|
+
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
5
|
+
|
|
6
|
+
# Capacity allocation accounting surface (#1419 Delivery Slice 4).
|
|
7
|
+
#
|
|
8
|
+
# `task capacity:show` derives per-bucket target-vs-actual mix from the vBRIEF
|
|
9
|
+
# lifecycle folders (filesystem-truth, offline) with outcome (rework) and cost
|
|
10
|
+
# overlays, and renders advisory mode when classified completions are below
|
|
11
|
+
# minSampleSize. It is a DISPLAY surface and always exits 0 on a valid project
|
|
12
|
+
# root (the companion `task verify:capacity` in tasks/verify.yml is the
|
|
13
|
+
# three-state advisory gate).
|
|
14
|
+
#
|
|
15
|
+
# Conventions (mirroring tasks/scope.yml / tasks/verify.yml):
|
|
16
|
+
# * `dir: '{{.USER_WORKING_DIR}}'` so the script's CWD is the consumer project
|
|
17
|
+
# root, not deft/.
|
|
18
|
+
# * `DEFT_ROOT` defined locally via joinPath so the script path resolves on
|
|
19
|
+
# Windows (#566).
|
|
20
|
+
# * `{{.CLI_ARGS}}` forwarded bare (no double quotes, #577) and NO `sources:` /
|
|
21
|
+
# `generates:` so go-task does not swallow flags (#574 / conventions/
|
|
22
|
+
# task-caching.md).
|
|
23
|
+
tasks:
|
|
24
|
+
show:
|
|
25
|
+
desc: "Capacity allocation target-vs-actual mix (advisory, offline). task capacity:show [-- --project-root <path>]"
|
|
26
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
27
|
+
deps:
|
|
28
|
+
- task: :ts:build
|
|
29
|
+
cmds:
|
|
30
|
+
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" capacity-show --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
|
|
31
|
+
|
|
32
|
+
backfill:
|
|
33
|
+
desc: "One-time capacity-bucket backfill for completed vBRIEFs (#1606): infer capacityBucket from origin-issue labels + stamp completedAt from git. Dry-run by default; idempotent; never touches cost. -- task capacity:backfill [-- --apply] [--window-only] [--cache-dir <path>] [--json]"
|
|
34
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
35
|
+
deps:
|
|
36
|
+
- task: :ts:build
|
|
37
|
+
cmds:
|
|
38
|
+
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" capacity-backfill --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
|
package/tasks/change.yml
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
vars:
|
|
4
|
+
# Per ../Taskfile.yml header: joinPath is evaluated eagerly by go-task
|
|
5
|
+
# templating and yields a native-separator absolute path so {{.DEFT_ROOT}}
|
|
6
|
+
# resolves correctly under uv on Windows (#566). Used here to pin
|
|
7
|
+
# `uv --project` against ancestor pyproject.toml leakage (#1011).
|
|
8
|
+
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
9
|
+
|
|
10
|
+
tasks:
|
|
11
|
+
changelog:check:
|
|
12
|
+
desc: Verify CHANGELOG.md has an [Unreleased] section with at least one entry
|
|
13
|
+
env:
|
|
14
|
+
PYTHONUTF8: "1"
|
|
15
|
+
cmds:
|
|
16
|
+
- cmd: >-
|
|
17
|
+
uv --project "{{.DEFT_ROOT}}" run python -c
|
|
18
|
+
"import sys, pathlib, re;
|
|
19
|
+
p = pathlib.Path('CHANGELOG.md');
|
|
20
|
+
(not p.exists()) and (print('FAIL: CHANGELOG.md not found'), sys.exit(1));
|
|
21
|
+
text = p.read_text('utf-8');
|
|
22
|
+
m = re.search(r'## \[Unreleased\][ \t]*\n(.*?)(?=\n## \[|$)', text, re.DOTALL);
|
|
23
|
+
(m is None) and (print('FAIL: No [Unreleased] section found in CHANGELOG.md'), sys.exit(1));
|
|
24
|
+
body = m.group(1);
|
|
25
|
+
entries = [l for l in body.splitlines() if l.strip().startswith('- ')];
|
|
26
|
+
(len(entries) == 0) and (print('FAIL: [Unreleased] section has no entries (no lines starting with \"- \")'), sys.exit(1));
|
|
27
|
+
print(f'OK: CHANGELOG.md [Unreleased] section has {len(entries)} entries')"
|
|
28
|
+
|
|
29
|
+
change:init:
|
|
30
|
+
desc: Create a new change proposal directory structure in history/changes/<name>/
|
|
31
|
+
cmds:
|
|
32
|
+
- cmd: >-
|
|
33
|
+
uv --project "{{.DEFT_ROOT}}" run python -c
|
|
34
|
+
"import sys, pathlib, json, re;
|
|
35
|
+
name = '{{.CLI_ARGS}}'.strip();
|
|
36
|
+
(not name) and (print('FAIL: Usage: task change:init -- <name>'), sys.exit(1));
|
|
37
|
+
(not re.match(r'^[\w][\w-]*$', name)) and (print('FAIL: Name must contain only alphanumeric characters, underscores, and hyphens'), sys.exit(1));
|
|
38
|
+
base = pathlib.Path('history/changes') / name;
|
|
39
|
+
base.exists() and (print(f'FAIL: {base} already exists'), sys.exit(1));
|
|
40
|
+
(base / 'specs').mkdir(parents=True, exist_ok=True);
|
|
41
|
+
proposal = {'vBRIEFInfo': {'version': '0.5'}, 'plan': {'title': name, 'status': 'draft', 'narratives': {'Problem': 'What is wrong or missing.', 'Change': 'What this proposal does about it.', 'Scope': 'In scope: ... Out of scope: ...', 'Impact': 'What existing code/specs are affected.', 'Risks': 'What could go wrong.', 'Approach': 'How to implement the change.', 'Alternatives': 'What else was considered and why not.', 'Dependencies': 'What must exist before this works.'}}};
|
|
42
|
+
(base / 'proposal.vbrief.json').write_text(json.dumps(proposal, indent=2) + chr(10), encoding='utf-8');
|
|
43
|
+
tasks = {'vBRIEFInfo': {'version': '0.5'}, 'plan': {'title': name, 'status': 'draft', 'items': [], 'edges': []}};
|
|
44
|
+
(base / 'tasks.vbrief.json').write_text(json.dumps(tasks, indent=2) + chr(10), encoding='utf-8');
|
|
45
|
+
print(f'OK: Created change proposal at {base}/');
|
|
46
|
+
[print(f' - {f}') for f in ['proposal.vbrief.json', 'tasks.vbrief.json', 'specs/']]"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
vars:
|
|
4
|
+
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
5
|
+
|
|
6
|
+
# Surface for the CHANGELOG.md union-merge helper (#911).
|
|
7
|
+
#
|
|
8
|
+
# Wraps scripts/resolve_changelog_unreleased.py, the canonical swarm-cascade
|
|
9
|
+
# Phase 6 Step 1 helper that replaces the older HEAD-take-and-discard pattern
|
|
10
|
+
# silently dropping rebasing-branch CHANGELOG entries on every cascade rebase.
|
|
11
|
+
# See skills/deft-directive-swarm/SKILL.md Phase 6 Step 1 for the manual-
|
|
12
|
+
# fallback contract -- this task is the canonical-path alternative.
|
|
13
|
+
#
|
|
14
|
+
# Per `conventions/task-caching.md` (#574): no `sources:` / `generates:`
|
|
15
|
+
# because the task forwards user-facing flags via {{.CLI_ARGS}} (notably
|
|
16
|
+
# --changelog-path / --dry-run / --quiet). The cached `cmds:` skip would
|
|
17
|
+
# silently discard a recovery flag, and the helper is fast enough that a
|
|
18
|
+
# real-time invocation does not need incremental-build caching.
|
|
19
|
+
tasks:
|
|
20
|
+
resolve-unreleased:
|
|
21
|
+
desc: "Union-merge CHANGELOG.md [Unreleased] conflicts (#911) -- task changelog:resolve-unreleased [-- --changelog-path PATH] [--dry-run]"
|
|
22
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
23
|
+
cmds:
|
|
24
|
+
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" changelog-resolve-unreleased {{.CLI_ARGS}}
|
package/tasks/ci.yml
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
vars:
|
|
4
|
+
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
5
|
+
|
|
6
|
+
# ci:* tasks for running the full CI pipeline locally so contributors
|
|
7
|
+
# catch CI failures before pushing.
|
|
8
|
+
#
|
|
9
|
+
# ci:local mirrors the step graph of .github/workflows/ci.yml on the
|
|
10
|
+
# host platform:
|
|
11
|
+
#
|
|
12
|
+
# - Linux: Python (uv sync + ruff + mypy + pytest --cov), Go test +
|
|
13
|
+
# cross-compile builds for linux/amd64 + darwin/arm64 +
|
|
14
|
+
# windows/amd64, and the existing Taskfile-level
|
|
15
|
+
# verifications (toolchain:check, verify:stubs,
|
|
16
|
+
# verify:links, verify:rule-ownership, vbrief:validate,
|
|
17
|
+
# build).
|
|
18
|
+
#
|
|
19
|
+
# - macOS: Same as Linux. The darwin/arm64 cross-compile is the
|
|
20
|
+
# native build path. /dev/null is the discard target for
|
|
21
|
+
# cross-compile output.
|
|
22
|
+
#
|
|
23
|
+
# - Windows: Same Python + Go + Taskfile-level steps; NUL replaces
|
|
24
|
+
# /dev/null as the cross-compile discard target.
|
|
25
|
+
# Additionally, when --matrix=windows is supplied the
|
|
26
|
+
# Windows-task-dispatch regression pytest guard-rails run
|
|
27
|
+
# -- those steps shell out to PowerShell and require a
|
|
28
|
+
# real Windows host (CI uses windows-latest).
|
|
29
|
+
#
|
|
30
|
+
# CLI_ARGS are forwarded so contributors can pass flags such as
|
|
31
|
+
# --matrix=linux, --skip-build, --verbose, and --no-fail-fast.
|
|
32
|
+
#
|
|
33
|
+
# Per conventions/task-caching.md, this task forwards {{.CLI_ARGS}} to
|
|
34
|
+
# a Python script that accepts user-facing flags (--skip-build,
|
|
35
|
+
# --no-fail-fast, etc.); declaring sources: / generates: would short-
|
|
36
|
+
# circuit the cmds: block and silently swallow those flags. Caching is
|
|
37
|
+
# intentionally absent.
|
|
38
|
+
#
|
|
39
|
+
# Companion script: scripts/ci_local.py
|
|
40
|
+
# Companion test: tests/cli/test_ci_local.py
|
|
41
|
+
|
|
42
|
+
tasks:
|
|
43
|
+
local:
|
|
44
|
+
desc: "Run the full CI pipeline locally (matrix-aware). Mirrors .github/workflows/ci.yml step graph; on Windows hosts --matrix=windows additionally runs the windows-task-dispatch regression guard-rails. Refs #233."
|
|
45
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
46
|
+
env:
|
|
47
|
+
PYTHONUTF8: "1"
|
|
48
|
+
cmds:
|
|
49
|
+
- uv --project "{{.DEFT_ROOT}}" run python "{{.DEFT_ROOT}}/scripts/ci_local.py" --root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
vars:
|
|
4
|
+
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
5
|
+
|
|
6
|
+
tasks:
|
|
7
|
+
validate-structure:
|
|
8
|
+
desc: "Validate authored codeStructure metadata and PR3 discipline rules (#1595)."
|
|
9
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
10
|
+
# Per conventions/task-caching.md: no sources/generates because this task
|
|
11
|
+
# forwards user-supplied paths and project-root flags via CLI_ARGS.
|
|
12
|
+
deps:
|
|
13
|
+
- task: :ts:build
|
|
14
|
+
cmds:
|
|
15
|
+
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" code-structure-validate --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
|
|
16
|
+
|
|
17
|
+
extract-default:
|
|
18
|
+
desc: "Emit the dependency-free default codebase-map artifact to stdout (#1595 PR3)."
|
|
19
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
20
|
+
deps:
|
|
21
|
+
- task: :ts:build
|
|
22
|
+
cmds:
|
|
23
|
+
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" codebase-default-extractor --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
|
|
24
|
+
|
|
25
|
+
provider-map:
|
|
26
|
+
desc: "Select an external codebase-map provider or fall back to the default artifact (#1595 PR3)."
|
|
27
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
28
|
+
deps:
|
|
29
|
+
- task: :ts:build
|
|
30
|
+
cmds:
|
|
31
|
+
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" codebase-provider --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
|
|
32
|
+
|
|
33
|
+
map:
|
|
34
|
+
desc: "Generate .planning/codebase/MAP.md from the selected codebase-map artifact (#1595 PR4)."
|
|
35
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
36
|
+
deps:
|
|
37
|
+
- task: :ts:build
|
|
38
|
+
cmds:
|
|
39
|
+
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" codebase-map --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
|
|
40
|
+
|
|
41
|
+
projection-registry:
|
|
42
|
+
desc: "Inspect registered codebase projection kinds (#1595 PR3)."
|
|
43
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
44
|
+
deps:
|
|
45
|
+
- task: :ts:build
|
|
46
|
+
cmds:
|
|
47
|
+
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" codebase-projection-registry {{.CLI_ARGS}}
|
package/tasks/commit.yml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
vars:
|
|
4
|
+
# Per ../Taskfile.yml header: joinPath is evaluated eagerly by go-task
|
|
5
|
+
# templating and yields a native-separator absolute path so {{.DEFT_ROOT}}
|
|
6
|
+
# resolves correctly under uv on Windows (#566). Used here to pin
|
|
7
|
+
# `uv --project` against ancestor pyproject.toml leakage (#1011).
|
|
8
|
+
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
9
|
+
|
|
10
|
+
tasks:
|
|
11
|
+
commit:lint:
|
|
12
|
+
desc: Validate HEAD commit message against conventional commit format
|
|
13
|
+
cmds:
|
|
14
|
+
- cmd: >-
|
|
15
|
+
uv --project "{{.DEFT_ROOT}}" run python -c
|
|
16
|
+
"import sys, re, subprocess;
|
|
17
|
+
result = subprocess.run(['git', 'log', '--format=%B', '-1'], capture_output=True, text=True);
|
|
18
|
+
(result.returncode != 0) and (print('FAIL: Could not read HEAD commit message'), sys.exit(1));
|
|
19
|
+
msg = result.stdout.strip();
|
|
20
|
+
subject = msg.splitlines()[0] if msg else '';
|
|
21
|
+
types = 'feat|fix|docs|chore|refactor|test|style|perf|ci|build|revert';
|
|
22
|
+
pattern = r'^(' + types + r')(\(.+\))?!?: .+';
|
|
23
|
+
ok = re.match(pattern, subject);
|
|
24
|
+
(not ok) and (print('FAIL: Commit message does not match conventional commit format'),
|
|
25
|
+
print(f' Got: {subject}'),
|
|
26
|
+
print(f' Expected: type(scope): description'),
|
|
27
|
+
print(f' Types: feat, fix, docs, chore, refactor, test, style, perf, ci, build, revert'),
|
|
28
|
+
sys.exit(1));
|
|
29
|
+
print(f'OK: Commit message is valid conventional commit');
|
|
30
|
+
print(f' Subject: {subject}')"
|
package/tasks/core.yml
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
vars:
|
|
4
|
+
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
5
|
+
|
|
6
|
+
tasks:
|
|
7
|
+
validate:
|
|
8
|
+
desc: Validate all markdown files
|
|
9
|
+
env:
|
|
10
|
+
PYTHONUTF8: "1"
|
|
11
|
+
cmds:
|
|
12
|
+
- cmd: >-
|
|
13
|
+
uv --project "{{.DEFT_ROOT}}" run python -c "from pathlib import Path;
|
|
14
|
+
files=[f for f in sorted(Path('.').rglob('*.md')) if '.git' not in f.parts and 'backup' not in f.parts];
|
|
15
|
+
[print(f'\u2713 {f}') for f in files];
|
|
16
|
+
print(f'\u2713 All {len(files)} markdown files validated')"
|
|
17
|
+
|
|
18
|
+
test:
|
|
19
|
+
desc: Run test suite
|
|
20
|
+
cmds:
|
|
21
|
+
# #1474: tolerate a missing tests/ directory. The installer (#1482)
|
|
22
|
+
# prunes the vendored .deft/core/tests/ from the consumer deposit, so in
|
|
23
|
+
# a vendored consumer `task deft:check` -> framework check -> core:test
|
|
24
|
+
# would otherwise run `pytest tests/` against a now-absent directory and
|
|
25
|
+
# exit with a path error instead of 0 (blocking #1474 acceptance a1).
|
|
26
|
+
# A cross-platform pathlib guard (no bare shell conditional, per the
|
|
27
|
+
# AGENTS.md Windows rules) skips the run with a clear notice when tests/
|
|
28
|
+
# is absent; the framework's own repo (tests/ present) still runs the
|
|
29
|
+
# full suite unchanged. The check targets the same CWD-relative `tests`
|
|
30
|
+
# path pytest would run against, so it is correct regardless of CWD.
|
|
31
|
+
- cmd: >-
|
|
32
|
+
uv --project "{{.DEFT_ROOT}}" run python -c "import sys, subprocess;
|
|
33
|
+
from pathlib import Path;
|
|
34
|
+
_exists = Path('tests').exists();
|
|
35
|
+
print('no tests/ (vendored consumer) -- skipping') if not _exists else None;
|
|
36
|
+
sys.exit(subprocess.run([sys.executable, '-m', 'pytest', 'tests']).returncode if _exists else 0)"
|
|
37
|
+
|
|
38
|
+
test:coverage:
|
|
39
|
+
desc: Run tests with coverage (fails if < 85%)
|
|
40
|
+
cmds:
|
|
41
|
+
- uv --project "{{.DEFT_ROOT}}" run pytest tests/ --cov --cov-report=html
|
|
42
|
+
|
|
43
|
+
fmt:
|
|
44
|
+
desc: Format Python code
|
|
45
|
+
cmds:
|
|
46
|
+
- uv --project "{{.DEFT_ROOT}}" run ruff format .
|
|
47
|
+
- uv --project "{{.DEFT_ROOT}}" run black .
|
|
48
|
+
|
|
49
|
+
lint:
|
|
50
|
+
desc: Lint and type-check Python code
|
|
51
|
+
cmds:
|
|
52
|
+
- uv --project "{{.DEFT_ROOT}}" run ruff check .
|
|
53
|
+
# #1475: bring the local type-check gate to parity with CI. The CI
|
|
54
|
+
# Python job (.github/workflows/ci.yml) runs `mypy tests/`, but this
|
|
55
|
+
# local gate previously checked only run.py -- so a type error under
|
|
56
|
+
# tests/ shipped green locally (task check -> core:lint) and reddened
|
|
57
|
+
# master after merge. The tests/ tree is now part of the gate; run.py
|
|
58
|
+
# is retained for its pre-existing local-only coverage. Both surfaces
|
|
59
|
+
# share the [tool.mypy] config in pyproject.toml, including the
|
|
60
|
+
# tests.* override that relaxes disallow_untyped_defs while still
|
|
61
|
+
# failing on real type mismatches under tests/.
|
|
62
|
+
#
|
|
63
|
+
# #1474: the same vendored-consumer guard core:test uses. The installer
|
|
64
|
+
# (#1482) prunes the vendored .deft/core/tests/, and `task deft:check`
|
|
65
|
+
# runs core:lint too, so an unconditional `mypy run.py tests/` would
|
|
66
|
+
# fail on the now-absent tests/ path. The cross-platform pathlib guard
|
|
67
|
+
# (no bare shell conditional, per the AGENTS.md Windows rules) appends
|
|
68
|
+
# tests/ to the mypy target list only when it exists; run.py (always in
|
|
69
|
+
# the payload) stays checked either way.
|
|
70
|
+
- cmd: >-
|
|
71
|
+
uv --project "{{.DEFT_ROOT}}" run python -c "import sys, subprocess;
|
|
72
|
+
from pathlib import Path;
|
|
73
|
+
targets = ['run.py'] + (['tests'] if Path('tests').exists() else []);
|
|
74
|
+
sys.exit(subprocess.run([sys.executable, '-m', 'mypy', *targets]).returncode)"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
build:
|
|
78
|
+
desc: Package framework for distribution (cross-platform via Python helper, #736)
|
|
79
|
+
env:
|
|
80
|
+
PYTHONUTF8: "1"
|
|
81
|
+
cmds:
|
|
82
|
+
# Single cross-platform dispatch (#736). The Python helper uses
|
|
83
|
+
# stdlib tarfile / zipfile with a canonical exclude list and
|
|
84
|
+
# auto-selects tar.gz on Linux/macOS, zip on Windows. The previous
|
|
85
|
+
# platform-split shape had the Windows branch missing the exclude
|
|
86
|
+
# list, ingesting .git history and the prior dist/ artifact.
|
|
87
|
+
# Regression-guarded by tests/content/test_taskfile_zip_parity.py.
|
|
88
|
+
- uv --project "{{.DEFT_ROOT}}" run python "{{.DEFT_ROOT}}/scripts/build_dist.py" --version "{{.VERSION}}"
|
|
89
|
+
|
|
90
|
+
clean:
|
|
91
|
+
desc: Clean generated artifacts (cross-platform via Python helper, #736)
|
|
92
|
+
env:
|
|
93
|
+
PYTHONUTF8: "1"
|
|
94
|
+
cmds:
|
|
95
|
+
# Single cross-platform dispatch (#736) -- mirrors the build target's
|
|
96
|
+
# simplification. Python's pathlib + shutil.rmtree handles the dist/
|
|
97
|
+
# directory removal identically on POSIX and Windows, replacing the
|
|
98
|
+
# prior rm -rf / Remove-Item duplication.
|
|
99
|
+
#
|
|
100
|
+
# The dist/ path is anchored at {{.DEFT_ROOT}} so `task clean` works
|
|
101
|
+
# the same way regardless of the operator's current working directory.
|
|
102
|
+
# The previous shape relied on `pathlib.Path('dist')` resolving against
|
|
103
|
+
# the inherited CWD, which silently no-ops when the operator runs
|
|
104
|
+
# `task -t tasks/core.yml clean` from a subdirectory (Greptile P2 on
|
|
105
|
+
# PR #773).
|
|
106
|
+
- cmd: >-
|
|
107
|
+
uv --project "{{.DEFT_ROOT}}" run python -c "import shutil, pathlib;
|
|
108
|
+
d = pathlib.Path(r'{{.DEFT_ROOT}}') / 'dist';
|
|
109
|
+
shutil.rmtree(d) if d.exists() else None;
|
|
110
|
+
print(f'Cleaned {d}')"
|
|
111
|
+
|
|
112
|
+
stats:
|
|
113
|
+
desc: Show framework statistics
|
|
114
|
+
cmds:
|
|
115
|
+
- cmd: >-
|
|
116
|
+
uv --project "{{.DEFT_ROOT}}" run python -c "from pathlib import Path;
|
|
117
|
+
v='{{.VERSION}}';
|
|
118
|
+
sep='='*42;
|
|
119
|
+
dirs=[('Core files','core'),('Languages','languages'),('Interfaces','interfaces'),('Tools','tools'),('Templates','templates')];
|
|
120
|
+
counts=[(n,len(list(Path(d).glob('*.md')))) for n,d in dirs];
|
|
121
|
+
total=len([f for f in Path('.').rglob('*.md') if '.git' not in str(f) and 'backup' not in str(f)]);
|
|
122
|
+
print(f'Deft Framework v{v} Statistics:');
|
|
123
|
+
print(sep);
|
|
124
|
+
[print(f'{n}: {c}') for n,c in counts];
|
|
125
|
+
print(f'Total files: {total}');
|
|
126
|
+
print(sep)"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
set: [errexit, nounset, pipefail]
|
|
4
|
+
|
|
5
|
+
vars:
|
|
6
|
+
CLOUDGOV_VERSION: v1.1.0
|
|
7
|
+
CLOUDGOV_UPSTREAM_DIR: deployments/cloud-gov/upstream
|
|
8
|
+
CLOUDGOV_EXPORT_DIR: .deft/cloud.gov
|
|
9
|
+
CLOUDGOV_ARCHIVE: '{{.CLOUDGOV_UPSTREAM_DIR}}/cloud-gov-instructions-{{.CLOUDGOV_VERSION}}.tar.gz'
|
|
10
|
+
CLOUDGOV_EXTRACT_DIR: '{{.CLOUDGOV_UPSTREAM_DIR}}/cloud-gov-instructions-1.1.0'
|
|
11
|
+
|
|
12
|
+
tasks:
|
|
13
|
+
cloudgov:sync:
|
|
14
|
+
desc: Sync pinned cloud-gov-instructions release to deployments/cloud-gov/upstream
|
|
15
|
+
cmds:
|
|
16
|
+
- mkdir -p {{.CLOUDGOV_UPSTREAM_DIR}}
|
|
17
|
+
- curl -L https://github.com/adhocteam/cloud-gov-instructions/archive/refs/tags/{{.CLOUDGOV_VERSION}}.tar.gz -o {{.CLOUDGOV_ARCHIVE}}
|
|
18
|
+
- tar -xzf {{.CLOUDGOV_ARCHIVE}} -C {{.CLOUDGOV_UPSTREAM_DIR}}
|
|
19
|
+
generates:
|
|
20
|
+
- '{{.CLOUDGOV_ARCHIVE}}'
|
|
21
|
+
- '{{.CLOUDGOV_EXTRACT_DIR}}'
|
|
22
|
+
|
|
23
|
+
cloudgov:export:
|
|
24
|
+
desc: Export Copilot-ready cloud.gov instructions to .deft/cloud.gov
|
|
25
|
+
vars:
|
|
26
|
+
OUT_DIR: '{{.OUT_DIR | default .CLOUDGOV_EXPORT_DIR}}'
|
|
27
|
+
cmds:
|
|
28
|
+
- mkdir -p {{.OUT_DIR}}/.github/instructions {{.OUT_DIR}}/.github/agents {{.OUT_DIR}}/.github/skills
|
|
29
|
+
- cp deployments/cloud-gov/overview.md {{.OUT_DIR}}/.github/copilot-instructions.md
|
|
30
|
+
- cp deployments/cloud-gov/deployment.md {{.OUT_DIR}}/.github/instructions/deployment.instructions.md
|
|
31
|
+
- cp deployments/cloud-gov/manifest.md {{.OUT_DIR}}/.github/instructions/manifest.instructions.md
|
|
32
|
+
- cp deployments/cloud-gov/services.md {{.OUT_DIR}}/.github/instructions/services.instructions.md
|
|
33
|
+
- cp deployments/cloud-gov/cicd.md {{.OUT_DIR}}/.github/instructions/cicd.instructions.md
|
|
34
|
+
- cp deployments/cloud-gov/security.md {{.OUT_DIR}}/.github/instructions/security.instructions.md
|
|
35
|
+
- cp deployments/cloud-gov/logging.md {{.OUT_DIR}}/.github/instructions/logging.instructions.md
|
|
36
|
+
- cp deployments/cloud-gov/agents.md {{.OUT_DIR}}/AGENTS.md
|
|
37
|
+
- cp deployments/cloud-gov/agents/compliance-docs.md {{.OUT_DIR}}/.github/agents/compliance-docs.agent.md
|
|
38
|
+
- cp deployments/cloud-gov/skills/cf-troubleshoot.md {{.OUT_DIR}}/.github/skills/cf-troubleshoot.md
|
|
39
|
+
- cp deployments/cloud-gov/LICENSE.md {{.OUT_DIR}}/LICENSE.md
|
|
40
|
+
sources:
|
|
41
|
+
- deployments/cloud-gov/**/*.md
|
|
42
|
+
generates:
|
|
43
|
+
- '{{.OUT_DIR}}/.github/copilot-instructions.md'
|
|
44
|
+
- '{{.OUT_DIR}}/.github/instructions/deployment.instructions.md'
|
|
45
|
+
- '{{.OUT_DIR}}/.github/instructions/manifest.instructions.md'
|
|
46
|
+
- '{{.OUT_DIR}}/.github/instructions/services.instructions.md'
|
|
47
|
+
- '{{.OUT_DIR}}/.github/instructions/cicd.instructions.md'
|
|
48
|
+
- '{{.OUT_DIR}}/.github/instructions/security.instructions.md'
|
|
49
|
+
- '{{.OUT_DIR}}/.github/instructions/logging.instructions.md'
|
|
50
|
+
- '{{.OUT_DIR}}/.github/agents/compliance-docs.agent.md'
|
|
51
|
+
- '{{.OUT_DIR}}/.github/skills/cf-troubleshoot.md'
|
|
52
|
+
- '{{.OUT_DIR}}/AGENTS.md'
|
|
53
|
+
- '{{.OUT_DIR}}/LICENSE.md'
|
|
54
|
+
method: checksum
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
# tasks/framework.yml -- framework-level introspection / upkeep tasks (#801).
|
|
4
|
+
#
|
|
5
|
+
# Hosts surfaces that interrogate the deft framework itself (rather than the
|
|
6
|
+
# consumer project). Currently only `framework:check-updates`, but this is
|
|
7
|
+
# the natural home for any future "is the deft framework healthy / current"
|
|
8
|
+
# probe (e.g. submodule SHA reconcile, .deft/core/run version vs marker, etc.).
|
|
9
|
+
#
|
|
10
|
+
# Per `conventions/task-caching.md` (#574): the check-updates task accepts a
|
|
11
|
+
# user-facing `--force` recovery flag (mapped to DEFT_FORCE_REMOTE_PROBE=1)
|
|
12
|
+
# and therefore MUST NOT declare `sources:` / `generates:` -- the cached
|
|
13
|
+
# `cmds:` skip would silently discard the recovery flag.
|
|
14
|
+
|
|
15
|
+
vars:
|
|
16
|
+
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
17
|
+
|
|
18
|
+
tasks:
|
|
19
|
+
check-updates:
|
|
20
|
+
desc: "Read-only remote-version probe (#801) -- task framework:check-updates [-- --force | --json]. Honors DEFT_NO_NETWORK=1 and DEFT_REMOTE_PROBE_TIMEOUT (default 5s)."
|
|
21
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
22
|
+
env:
|
|
23
|
+
PYTHONUTF8: "1"
|
|
24
|
+
# When the operator passes `--force`, the task wrapper sets
|
|
25
|
+
# DEFT_FORCE_REMOTE_PROBE=1 so the gate-integration helper bypasses
|
|
26
|
+
# the 24h throttle. The `run` CLI surface (`run check-updates`) is
|
|
27
|
+
# already idempotent (does not write to the throttle file), so this
|
|
28
|
+
# env var only affects callers that probe through the upgrade gate.
|
|
29
|
+
DEFT_FORCE_REMOTE_PROBE: '{{if (mustRegexMatch "(^|\\s)--force(\\s|$)" .CLI_ARGS)}}1{{else}}{{.DEFT_FORCE_REMOTE_PROBE | default ""}}{{end}}'
|
|
30
|
+
cmds:
|
|
31
|
+
# Strip our own `--force` from the args we pass through to `run` so it
|
|
32
|
+
# does not surface as an unknown flag in the JSON / text output. Other
|
|
33
|
+
# supported flags (e.g. `--json`) flow through unchanged.
|
|
34
|
+
#
|
|
35
|
+
# #1059: invoke Python through `uv --project "{{.DEFT_ROOT}}" run python`
|
|
36
|
+
# rather than a bare `python3`. On Windows the bare `python3` command
|
|
37
|
+
# resolves to the Microsoft Store app-execution-alias stub (exit 49) on
|
|
38
|
+
# default-configured hosts where the user installed Python via the
|
|
39
|
+
# official installer, so the wrapper aborted before `run check-updates`
|
|
40
|
+
# ever started. The `uv` wrapper matches the canonical pattern used by
|
|
41
|
+
# every other tasks/*.yml file (see e.g. `tasks/prd.yml`,
|
|
42
|
+
# `tasks/vbrief.yml`) and pins the project root via #1011 so the
|
|
43
|
+
# uv environment never walks up into a hostile ancestor pyproject.
|
|
44
|
+
- >-
|
|
45
|
+
uv --project "{{.DEFT_ROOT}}" run python "{{.DEFT_ROOT}}/run" check-updates
|
|
46
|
+
{{regexReplaceAll "(^|\\s)--force(\\s|$)" .CLI_ARGS " "}}
|
|
47
|
+
|
|
48
|
+
doctor:
|
|
49
|
+
# #1272: the legacy ``task framework:doctor`` surface is REDACTED.
|
|
50
|
+
# ``task doctor`` (root Taskfile.yml shim for ``.deft/core/run doctor``)
|
|
51
|
+
# is now the canonical doctor entry point and owns the install-integrity
|
|
52
|
+
# probe, the root Taskfile.yml include diagnostics, and the optional
|
|
53
|
+
# interactive repair path. This shim prints a single-line redaction
|
|
54
|
+
# notice and exits 0 so legacy callers do not crash, while operators are
|
|
55
|
+
# nudged at the canonical surface. The Python probe at
|
|
56
|
+
# ``scripts/framework_doctor.py`` is still exercised internally by the
|
|
57
|
+
# upgrade gate's ``_maybe_run_framework_doctor`` advisory; nothing about
|
|
58
|
+
# that pathway changes.
|
|
59
|
+
desc: "Deprecated doctor surface (#1272) -- prints redaction; use `task doctor` (or `.deft/core/run doctor`) instead."
|
|
60
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
61
|
+
env:
|
|
62
|
+
PYTHONUTF8: "1"
|
|
63
|
+
cmds:
|
|
64
|
+
# Cross-platform redaction line. go-task runs every ``cmd:`` through
|
|
65
|
+
# its embedded mvdan/sh POSIX-sh interpreter on every host (Windows,
|
|
66
|
+
# macOS, Linux), so a single ``echo`` invocation is portable and
|
|
67
|
+
# strips the surrounding quotes uniformly -- emitting exactly:
|
|
68
|
+
# redacted use run doctor instead
|
|
69
|
+
# The previous Windows branch shelled out to ``pwsh`` (PowerShell 7+),
|
|
70
|
+
# which is NOT present on stock Windows 10 / 11 (only ``powershell.exe``
|
|
71
|
+
# ships out of the box) so any consumer without PowerShell 7+ installed
|
|
72
|
+
# would see ``pwsh: not found`` instead of the redaction notice. Letting
|
|
73
|
+
# mvdan/sh handle the echo sidesteps the shell-dependence entirely.
|
|
74
|
+
- echo "redacted use run doctor instead"
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
vars:
|
|
4
|
+
# Per ../Taskfile.yml header: joinPath is evaluated eagerly by go-task
|
|
5
|
+
# templating and yields a native-separator absolute path so {{.DEFT_ROOT}}
|
|
6
|
+
# resolves correctly under uv on Windows (#566). Used here to pin
|
|
7
|
+
# `uv --project` against ancestor pyproject.toml leakage (#1011).
|
|
8
|
+
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
9
|
+
|
|
10
|
+
tasks:
|
|
11
|
+
install:
|
|
12
|
+
desc: Install deft (dev convenience -- end users should use the compiled binary from GitHub Releases)
|
|
13
|
+
cmds:
|
|
14
|
+
- go run ./cmd/deft-install/
|
|
15
|
+
|
|
16
|
+
uninstall:
|
|
17
|
+
desc: Remove deft entry from AGENTS.md
|
|
18
|
+
cmds:
|
|
19
|
+
- cmd: >-
|
|
20
|
+
uv --project "{{.DEFT_ROOT}}" run python -c "from pathlib import Path;
|
|
21
|
+
f=Path('AGENTS.md');
|
|
22
|
+
t=f.read_text('utf-8') if f.exists() else '';
|
|
23
|
+
lines=t.splitlines(keepends=True);
|
|
24
|
+
out=''.join(l for l in lines if not l.startswith('See deft/main.md') and not l.startswith('Skills: deft/skills/'));
|
|
25
|
+
f.write_text(out,'utf-8') if f.exists() else None;
|
|
26
|
+
print('Removed deft entry from AGENTS.md' if out!=t else 'No deft entry found in AGENTS.md')"
|
|
27
|
+
|
|
28
|
+
# User-facing upgrade entrypoint (#1061). Wraps the canonical
|
|
29
|
+
# ``run upgrade`` command (`cmd_upgrade` in ./run) which:
|
|
30
|
+
# 1. Writes / refreshes the bare ``.deft-version`` marker.
|
|
31
|
+
# 2. Writes the canonical YAML provenance manifest at
|
|
32
|
+
# ``<install>/VERSION`` (#1046 PR-B AC-4) -- including the
|
|
33
|
+
# ``install_root`` field added in #1062.
|
|
34
|
+
# 3. Delegates to ``cmd_agents_refresh`` so the AGENTS.md managed
|
|
35
|
+
# section is brought to the current rendered template (v3 marker
|
|
36
|
+
# with sha/refreshed/session attributes, #1046 PR-B AC-5).
|
|
37
|
+
# This wrapper exists so the ``framework:doctor`` failure prose and
|
|
38
|
+
# ``docs/install-manifest.md`` can cite a real Taskfile target rather
|
|
39
|
+
# than a raw ``run`` invocation. Idempotent on re-run: a second
|
|
40
|
+
# invocation against a current manifest + AGENTS.md is a no-op.
|
|
41
|
+
#
|
|
42
|
+
# Per ``conventions/task-caching.md`` (#574): no ``sources:`` /
|
|
43
|
+
# ``generates:`` because the task is mutating + must run on every
|
|
44
|
+
# invocation. CLI_ARGS is explicitly cleared (``vars: { CLI_ARGS: "" }``)
|
|
45
|
+
# so any operator-supplied ``-- <flags>`` are deterministically dropped
|
|
46
|
+
# before reaching ``run upgrade``: go-task only forwards ``{{.CLI_ARGS}}``
|
|
47
|
+
# when a ``cmds`` line references it, but pinning the var to empty makes
|
|
48
|
+
# the contract explicit AND defends against a future edit that
|
|
49
|
+
# accidentally appends ``{{.CLI_ARGS}}`` to the dispatch line (SLizard P1
|
|
50
|
+
# on PR #1067 -- ``cmd_upgrade`` does not currently accept flags; future
|
|
51
|
+
# flag additions land deliberately, not implicitly via Taskfile drift).
|
|
52
|
+
upgrade:
|
|
53
|
+
desc: "Upgrade deft framework: refresh AGENTS.md to current marker, write canonical install manifest, regenerate .deft-version derivative (#1061). Wraps `run upgrade`."
|
|
54
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
55
|
+
env:
|
|
56
|
+
PYTHONUTF8: "1"
|
|
57
|
+
vars:
|
|
58
|
+
CLI_ARGS: ""
|
|
59
|
+
cmds:
|
|
60
|
+
- uv --project "{{.DEFT_ROOT}}" run python "{{.DEFT_ROOT}}/run" upgrade
|
package/tasks/issue.yml
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
|
|
3
|
+
vars:
|
|
4
|
+
DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
|
|
5
|
+
|
|
6
|
+
# issue ingest task.
|
|
7
|
+
#
|
|
8
|
+
# IMPORTANT: runs from the consumer project root (``dir:
|
|
9
|
+
# '{{.USER_WORKING_DIR}}'``) so ``gh`` and ``git`` commands executed by
|
|
10
|
+
# ``scripts/issue_ingest.py`` resolve against the CONSUMER's remote, not
|
|
11
|
+
# deftai/directive (#538). The explicit ``--project-root`` flag makes the
|
|
12
|
+
# intent clear to the script and gives it a stable anchor even if Task's
|
|
13
|
+
# ``dir:`` semantics ever change. Script path dispatched via {{.DEFT_ROOT}}
|
|
14
|
+
# (defined locally in this file's `vars:` block via
|
|
15
|
+
# ``{{joinPath .TASKFILE_DIR ".."}}`` -- see ../Taskfile.yml for why
|
|
16
|
+
# root-level definition is avoided) to keep the path traversal-free and
|
|
17
|
+
# avoid the {{.TASKFILE_DIR}}/.. form that breaks on Windows under
|
|
18
|
+
# `uv --project "{{.DEFT_ROOT}}" run python` (#566).
|
|
19
|
+
|
|
20
|
+
tasks:
|
|
21
|
+
_ensure-ts:
|
|
22
|
+
internal: true
|
|
23
|
+
desc: "Build the TS engine before issue gates (#1828 s4)"
|
|
24
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
25
|
+
cmds:
|
|
26
|
+
- pnpm --dir "{{.DEFT_ROOT}}" run build
|
|
27
|
+
|
|
28
|
+
ingest:
|
|
29
|
+
desc: "Ingest GitHub issues as scope vBRIEFs (single <N> or --all [--label L] [--status S] [--dry-run])"
|
|
30
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
31
|
+
deps:
|
|
32
|
+
- _ensure-ts
|
|
33
|
+
cmds:
|
|
34
|
+
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" issue-ingest --vbrief-dir "{{.USER_WORKING_DIR}}/vbrief" --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
|
|
35
|
+
|
|
36
|
+
# issue emit task -- the write-direction counterpart to issue:ingest
|
|
37
|
+
# (#1274 Change 2). Files GitHub issue(s) from scope vBRIEFs and records
|
|
38
|
+
# the issue URL back into each vBRIEF's references[]. Runs from the
|
|
39
|
+
# consumer project root (``dir: '{{.USER_WORKING_DIR}}'``) so ``gh`` /
|
|
40
|
+
# ``git`` resolve against the CONSUMER's remote, not deftai/directive
|
|
41
|
+
# (#538); --project-root anchors repo detection and glob expansion.
|
|
42
|
+
# Honors --dry-run AND DEFT_NO_NETWORK=1 (plan only; no forge write).
|
|
43
|
+
emit:
|
|
44
|
+
desc: "File GitHub issue(s) from scope vBRIEF(s) (<path> | --umbrella <glob> | --per-vbrief <glob> [--dry-run])"
|
|
45
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
46
|
+
deps: [":ts:build"]
|
|
47
|
+
env:
|
|
48
|
+
PYTHONUTF8: "1"
|
|
49
|
+
cmds:
|
|
50
|
+
- node "{{.DEFT_ROOT}}/packages/cli/dist/bin.js" issue-emit --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
|