@lumenflow/cli 3.1.3 → 3.2.1
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/dist/agent-issues-query.js.map +1 -0
- package/dist/agent-log-issue.js.map +1 -0
- package/dist/agent-session-end.js.map +1 -0
- package/dist/agent-session.js.map +1 -0
- package/dist/backlog-prune.js.map +1 -0
- package/dist/cli-entry-point.js +139 -0
- package/dist/cli-entry-point.js.map +1 -0
- package/dist/commands/integrate.js.map +1 -0
- package/dist/commands.js.map +1 -0
- package/dist/config-get.js.map +1 -0
- package/dist/config-set.js.map +1 -0
- package/dist/constants.js +98 -0
- package/dist/constants.js.map +1 -0
- package/dist/delegation-list.js.map +1 -0
- package/dist/deps-add.js +259 -0
- package/dist/deps-add.js.map +1 -0
- package/dist/deps-remove.js +105 -0
- package/dist/deps-remove.js.map +1 -0
- package/dist/docs-sync.js.map +1 -0
- package/dist/doctor.js.map +1 -0
- package/dist/file-delete.js.map +1 -0
- package/dist/file-edit.js.map +1 -0
- package/dist/file-read.js.map +1 -0
- package/dist/file-write.js.map +1 -0
- package/dist/flow-bottlenecks.js.map +1 -0
- package/dist/flow-report.js.map +1 -0
- package/dist/formatters.js +151 -0
- package/dist/formatters.js.map +1 -0
- package/dist/gate-defaults.js +137 -0
- package/dist/gate-defaults.js.map +1 -0
- package/dist/gate-registry.js +73 -0
- package/dist/gate-registry.js.map +1 -0
- package/dist/gates-graceful-degradation.js +153 -0
- package/dist/gates-graceful-degradation.js.map +1 -0
- package/dist/gates-plan-resolvers.js +190 -0
- package/dist/gates-plan-resolvers.js.map +1 -0
- package/dist/gates-runners.js +545 -0
- package/dist/gates-runners.js.map +1 -0
- package/dist/gates-types.js +4 -0
- package/dist/gates-types.js.map +1 -0
- package/dist/gates-utils.js +333 -0
- package/dist/gates-utils.js.map +1 -0
- package/dist/gates.js.map +1 -0
- package/dist/git-branch.js.map +1 -0
- package/dist/git-diff.js.map +1 -0
- package/dist/git-log.js.map +1 -0
- package/dist/git-status.js.map +1 -0
- package/dist/guard-locked.js +172 -0
- package/dist/guard-locked.js.map +1 -0
- package/dist/guard-main-branch.js +217 -0
- package/dist/guard-main-branch.js.map +1 -0
- package/dist/guard-worktree-commit.js +163 -0
- package/dist/guard-worktree-commit.js.map +1 -0
- package/dist/hooks/auto-checkpoint-utils.js +54 -0
- package/dist/hooks/auto-checkpoint-utils.js.map +1 -0
- package/dist/hooks/enforcement-checks.js +399 -0
- package/dist/hooks/enforcement-checks.js.map +1 -0
- package/dist/hooks/enforcement-generator.js +139 -0
- package/dist/hooks/enforcement-generator.js.map +1 -0
- package/dist/hooks/enforcement-sync.js +380 -0
- package/dist/hooks/enforcement-sync.js.map +1 -0
- package/dist/hooks/generators/auto-checkpoint.js +125 -0
- package/dist/hooks/generators/auto-checkpoint.js.map +1 -0
- package/dist/hooks/generators/enforce-worktree.js +190 -0
- package/dist/hooks/generators/enforce-worktree.js.map +1 -0
- package/dist/hooks/generators/index.js +18 -0
- package/dist/hooks/generators/index.js.map +1 -0
- package/dist/hooks/generators/pre-compact-checkpoint.js +136 -0
- package/dist/hooks/generators/pre-compact-checkpoint.js.map +1 -0
- package/dist/hooks/generators/require-wu.js +117 -0
- package/dist/hooks/generators/require-wu.js.map +1 -0
- package/dist/hooks/generators/session-start-recovery.js +103 -0
- package/dist/hooks/generators/session-start-recovery.js.map +1 -0
- package/dist/hooks/generators/signal-utils.js +54 -0
- package/dist/hooks/generators/signal-utils.js.map +1 -0
- package/dist/hooks/generators/warn-incomplete.js +67 -0
- package/dist/hooks/generators/warn-incomplete.js.map +1 -0
- package/dist/hooks/index.js +10 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/init-detection.js +232 -0
- package/dist/init-detection.js.map +1 -0
- package/dist/init-lane-validation.js +147 -0
- package/dist/init-lane-validation.js.map +1 -0
- package/dist/init-scaffolding.js +158 -0
- package/dist/init-scaffolding.js.map +1 -0
- package/dist/init-templates.js +1983 -0
- package/dist/init-templates.js.map +1 -0
- package/dist/init.js.map +1 -0
- package/dist/initiative-add-wu.js.map +1 -0
- package/dist/initiative-bulk-assign-wus.js.map +1 -0
- package/dist/initiative-create.js.map +1 -0
- package/dist/initiative-edit.js.map +1 -0
- package/dist/initiative-list.js.map +1 -0
- package/dist/initiative-plan.js.map +1 -0
- package/dist/initiative-remove-wu.js.map +1 -0
- package/dist/initiative-status.js.map +1 -0
- package/dist/lane-edit.js.map +1 -0
- package/dist/lane-health.js.map +1 -0
- package/dist/lane-lifecycle-process.js +381 -0
- package/dist/lane-lifecycle-process.js.map +1 -0
- package/dist/lane-lock.js.map +1 -0
- package/dist/lane-setup.js.map +1 -0
- package/dist/lane-status.js.map +1 -0
- package/dist/lane-suggest.js.map +1 -0
- package/dist/lane-validate.js.map +1 -0
- package/dist/lifecycle-regression-harness.js +181 -0
- package/dist/lifecycle-regression-harness.js.map +1 -0
- package/dist/lumenflow-upgrade.js +18 -10
- package/dist/lumenflow-upgrade.js.map +1 -0
- package/dist/mem-checkpoint.js.map +1 -0
- package/dist/mem-cleanup.js.map +1 -0
- package/dist/mem-context.js.map +1 -0
- package/dist/mem-create.js.map +1 -0
- package/dist/mem-delete.js.map +1 -0
- package/dist/mem-export.js.map +1 -0
- package/dist/mem-inbox.js.map +1 -0
- package/dist/mem-index.js +214 -0
- package/dist/mem-index.js.map +1 -0
- package/dist/mem-init.js.map +1 -0
- package/dist/mem-profile.js +210 -0
- package/dist/mem-profile.js.map +1 -0
- package/dist/mem-promote.js +257 -0
- package/dist/mem-promote.js.map +1 -0
- package/dist/mem-ready.js.map +1 -0
- package/dist/mem-recover.js.map +1 -0
- package/dist/mem-signal.js.map +1 -0
- package/dist/mem-start.js.map +1 -0
- package/dist/mem-summarize.js.map +1 -0
- package/dist/mem-triage.js.map +1 -0
- package/dist/merge-block.js +225 -0
- package/dist/merge-block.js.map +1 -0
- package/dist/metrics-cli.js.map +1 -0
- package/dist/metrics-snapshot.js.map +1 -0
- package/dist/object-guards.js +9 -0
- package/dist/object-guards.js.map +1 -0
- package/dist/onboard.js.map +1 -0
- package/dist/onboarding-smoke-test.js +432 -0
- package/dist/onboarding-smoke-test.js.map +1 -0
- package/dist/orchestrate-init-status.js.map +1 -0
- package/dist/orchestrate-initiative.js.map +1 -0
- package/dist/orchestrate-monitor.js.map +1 -0
- package/dist/pack-author.js.map +1 -0
- package/dist/pack-hash.js.map +1 -0
- package/dist/pack-install.js.map +1 -0
- package/dist/pack-publish.js.map +1 -0
- package/dist/pack-scaffold.js.map +1 -0
- package/dist/pack-search.js.map +1 -0
- package/dist/pack-validate.js.map +1 -0
- package/dist/plan-create.js.map +1 -0
- package/dist/plan-edit.js.map +1 -0
- package/dist/plan-link.js.map +1 -0
- package/dist/plan-promote.js.map +1 -0
- package/dist/public-manifest.js +931 -0
- package/dist/public-manifest.js.map +1 -0
- package/dist/release.js +664 -116
- package/dist/release.js.map +1 -0
- package/dist/rotate-progress.js +253 -0
- package/dist/rotate-progress.js.map +1 -0
- package/dist/session-coordinator.js +303 -0
- package/dist/session-coordinator.js.map +1 -0
- package/dist/shared-validators.js +81 -0
- package/dist/shared-validators.js.map +1 -0
- package/dist/signal-cleanup.js.map +1 -0
- package/dist/state-bootstrap.js.map +1 -0
- package/dist/state-cleanup.js.map +1 -0
- package/dist/state-doctor-fix.js +226 -0
- package/dist/state-doctor-fix.js.map +1 -0
- package/dist/state-doctor-stamps.js +23 -0
- package/dist/state-doctor-stamps.js.map +1 -0
- package/dist/state-doctor.js.map +1 -0
- package/dist/strict-progress.js +255 -0
- package/dist/strict-progress.js.map +1 -0
- package/dist/sync-templates.js.map +1 -0
- package/dist/task-claim.js.map +1 -0
- package/dist/trace-gen.js +401 -0
- package/dist/trace-gen.js.map +1 -0
- package/dist/validate-agent-skills.js +224 -0
- package/dist/validate-agent-skills.js.map +1 -0
- package/dist/validate-agent-sync.js +152 -0
- package/dist/validate-agent-sync.js.map +1 -0
- package/dist/validate-backlog-sync.js +77 -0
- package/dist/validate-backlog-sync.js.map +1 -0
- package/dist/validate-skills-spec.js +211 -0
- package/dist/validate-skills-spec.js.map +1 -0
- package/dist/validate.js.map +1 -0
- package/dist/validator-defaults.js +107 -0
- package/dist/validator-defaults.js.map +1 -0
- package/dist/validator-registry.js +71 -0
- package/dist/validator-registry.js.map +1 -0
- package/dist/workspace-init.js.map +1 -0
- package/dist/wu-block.js.map +1 -0
- package/dist/wu-brief.js.map +1 -0
- package/dist/wu-claim-branch.js +123 -0
- package/dist/wu-claim-branch.js.map +1 -0
- package/dist/wu-claim-cloud.js +79 -0
- package/dist/wu-claim-cloud.js.map +1 -0
- package/dist/wu-claim-mode.js +82 -0
- package/dist/wu-claim-mode.js.map +1 -0
- package/dist/wu-claim-output.js +85 -0
- package/dist/wu-claim-output.js.map +1 -0
- package/dist/wu-claim-repair-guidance.js +12 -0
- package/dist/wu-claim-repair-guidance.js.map +1 -0
- package/dist/wu-claim-resume-handler.js +87 -0
- package/dist/wu-claim-resume-handler.js.map +1 -0
- package/dist/wu-claim-state.js +581 -0
- package/dist/wu-claim-state.js.map +1 -0
- package/dist/wu-claim-validation.js +458 -0
- package/dist/wu-claim-validation.js.map +1 -0
- package/dist/wu-claim-worktree.js +238 -0
- package/dist/wu-claim-worktree.js.map +1 -0
- package/dist/wu-claim.js.map +1 -0
- package/dist/wu-cleanup-cloud.js +78 -0
- package/dist/wu-cleanup-cloud.js.map +1 -0
- package/dist/wu-cleanup.js.map +1 -0
- package/dist/wu-code-path-coverage.js +83 -0
- package/dist/wu-code-path-coverage.js.map +1 -0
- package/dist/wu-create-cloud.js +30 -0
- package/dist/wu-create-cloud.js.map +1 -0
- package/dist/wu-create-content.js +264 -0
- package/dist/wu-create-content.js.map +1 -0
- package/dist/wu-create-readiness.js +59 -0
- package/dist/wu-create-readiness.js.map +1 -0
- package/dist/wu-create-validation.js +128 -0
- package/dist/wu-create-validation.js.map +1 -0
- package/dist/wu-create.js.map +1 -0
- package/dist/wu-delegate.js.map +1 -0
- package/dist/wu-delete.js.map +1 -0
- package/dist/wu-deps.js.map +1 -0
- package/dist/wu-done-auto-cleanup.js +194 -0
- package/dist/wu-done-auto-cleanup.js.map +1 -0
- package/dist/wu-done-check.js +38 -0
- package/dist/wu-done-check.js.map +1 -0
- package/dist/wu-done-cloud.js +48 -0
- package/dist/wu-done-cloud.js.map +1 -0
- package/dist/wu-done-decay.js +83 -0
- package/dist/wu-done-decay.js.map +1 -0
- package/dist/wu-done.js.map +1 -0
- package/dist/wu-edit-operations.js +399 -0
- package/dist/wu-edit-operations.js.map +1 -0
- package/dist/wu-edit-validators.js +282 -0
- package/dist/wu-edit-validators.js.map +1 -0
- package/dist/wu-edit.js.map +1 -0
- package/dist/wu-infer-lane.js.map +1 -0
- package/dist/wu-preflight.js.map +1 -0
- package/dist/wu-prep.js.map +1 -0
- package/dist/wu-proto.js.map +1 -0
- package/dist/wu-prune.js.map +1 -0
- package/dist/wu-recover.js.map +1 -0
- package/dist/wu-release.js.map +1 -0
- package/dist/wu-repair.js.map +1 -0
- package/dist/wu-sandbox.js.map +1 -0
- package/dist/wu-spawn-completion.js +58 -0
- package/dist/wu-spawn-completion.js.map +1 -0
- package/dist/wu-spawn-prompt-builders.js +1190 -0
- package/dist/wu-spawn-prompt-builders.js.map +1 -0
- package/dist/wu-spawn-strategy-resolver.js +322 -0
- package/dist/wu-spawn-strategy-resolver.js.map +1 -0
- package/dist/wu-spawn.js +59 -0
- package/dist/wu-spawn.js.map +1 -0
- package/dist/wu-state-cloud.js +41 -0
- package/dist/wu-state-cloud.js.map +1 -0
- package/dist/wu-status.js.map +1 -0
- package/dist/wu-unblock.js.map +1 -0
- package/dist/wu-unlock-lane.js.map +1 -0
- package/dist/wu-validate.js.map +1 -0
- package/package.json +8 -10
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* @file generators/warn-incomplete.ts
|
|
5
|
+
* Generate the warn-incomplete.sh hook script content (WU-1367).
|
|
6
|
+
*
|
|
7
|
+
* Extracted from enforcement-generator.ts by WU-1645.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Generate the warn-incomplete.sh hook script content.
|
|
11
|
+
*
|
|
12
|
+
* This Stop hook warns when session ends without wu:done.
|
|
13
|
+
* Always exits 0 (warning only, never blocks).
|
|
14
|
+
*/
|
|
15
|
+
export function generateWarnIncompleteScript() {
|
|
16
|
+
// Note: Shell variable escapes (\$, \") are intentional for the generated bash script
|
|
17
|
+
/* eslint-disable no-useless-escape */
|
|
18
|
+
return `#!/bin/bash
|
|
19
|
+
#
|
|
20
|
+
# warn-incomplete.sh (WU-1367)
|
|
21
|
+
#
|
|
22
|
+
# Stop hook that warns when session ends without wu:done.
|
|
23
|
+
# This is advisory only - never blocks session termination.
|
|
24
|
+
#
|
|
25
|
+
# Exit codes:
|
|
26
|
+
# 0 = Always (warnings only)
|
|
27
|
+
#
|
|
28
|
+
|
|
29
|
+
SCRIPT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
|
|
30
|
+
|
|
31
|
+
if [[ -z "\${CLAUDE_PROJECT_DIR:-}" ]]; then
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
MAIN_REPO_PATH="\$CLAUDE_PROJECT_DIR"
|
|
36
|
+
WORKTREES_DIR="\${MAIN_REPO_PATH}/worktrees"
|
|
37
|
+
|
|
38
|
+
# Check for active worktrees
|
|
39
|
+
if [[ ! -d "\$WORKTREES_DIR" ]]; then
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
WORKTREE_COUNT=\$(find "\$WORKTREES_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l)
|
|
44
|
+
if [[ "\$WORKTREE_COUNT" -eq 0 ]]; then
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Get active worktree names
|
|
49
|
+
ACTIVE_WORKTREES=\$(find "\$WORKTREES_DIR" -mindepth 1 -maxdepth 1 -type d -printf '%f\\n' 2>/dev/null | head -5 | tr '\\n' ', ' | sed 's/,\$//')
|
|
50
|
+
|
|
51
|
+
echo "" >&2
|
|
52
|
+
echo "=== Session Completion Reminder ===" >&2
|
|
53
|
+
echo "" >&2
|
|
54
|
+
echo "You have active worktrees: \$ACTIVE_WORKTREES" >&2
|
|
55
|
+
echo "" >&2
|
|
56
|
+
echo "If your work is complete, remember to run:" >&2
|
|
57
|
+
echo " pnpm wu:prep --id WU-XXXX (from worktree)" >&2
|
|
58
|
+
echo " pnpm wu:done --id WU-XXXX (from main)" >&2
|
|
59
|
+
echo "" >&2
|
|
60
|
+
echo "If work is incomplete, it will be preserved in the worktree." >&2
|
|
61
|
+
echo "====================================" >&2
|
|
62
|
+
|
|
63
|
+
exit 0
|
|
64
|
+
`;
|
|
65
|
+
/* eslint-enable no-useless-escape */
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=warn-incomplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warn-incomplete.js","sourceRoot":"","sources":["../../../src/hooks/generators/warn-incomplete.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,yCAAyC;AAEzC;;;;;GAKG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B;IAC1C,sFAAsF;IACtF,sCAAsC;IACtC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CR,CAAC;IACA,qCAAqC;AACvC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* @file hooks/index.ts
|
|
5
|
+
* Claude Code enforcement hooks module (WU-1367)
|
|
6
|
+
*/
|
|
7
|
+
export * from './enforcement-generator.js';
|
|
8
|
+
export * from './enforcement-checks.js';
|
|
9
|
+
export * from './enforcement-sync.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,yCAAyC;AAEzC;;;GAGG;AAEH,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,yCAAyC;AAEzC;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE7D,uDAAuD;AACvD,OAAO,EACL,YAAY,EACZ,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,aAAa,GACd,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* @file init-detection.ts
|
|
5
|
+
* Detection helpers for LumenFlow init command (WU-1644)
|
|
6
|
+
*
|
|
7
|
+
* Extracted from init.ts -- environment detection, prerequisite checks,
|
|
8
|
+
* git state inspection, and docs structure detection.
|
|
9
|
+
*/
|
|
10
|
+
import * as fs from 'node:fs';
|
|
11
|
+
import * as path from 'node:path';
|
|
12
|
+
import { execFileSync } from 'node:child_process';
|
|
13
|
+
import { LUMENFLOW_CLIENT_IDS } from '@lumenflow/core';
|
|
14
|
+
const DEFAULT_CLIENT_CLAUDE = LUMENFLOW_CLIENT_IDS.CLAUDE_CODE;
|
|
15
|
+
/**
|
|
16
|
+
* WU-1177: Detect IDE environment from environment variables
|
|
17
|
+
* Auto-detects which AI coding assistant is running
|
|
18
|
+
*/
|
|
19
|
+
export function detectIDEEnvironment() {
|
|
20
|
+
// Claude Code detection (highest priority - most specific)
|
|
21
|
+
if (process.env.CLAUDE_PROJECT_DIR || process.env.CLAUDE_CODE) {
|
|
22
|
+
return 'claude';
|
|
23
|
+
}
|
|
24
|
+
// Cursor detection
|
|
25
|
+
const cursorVars = Object.keys(process.env).filter((key) => key.startsWith('CURSOR_'));
|
|
26
|
+
if (cursorVars.length > 0) {
|
|
27
|
+
return 'cursor';
|
|
28
|
+
}
|
|
29
|
+
// Windsurf detection
|
|
30
|
+
const windsurfVars = Object.keys(process.env).filter((key) => key.startsWith('WINDSURF_'));
|
|
31
|
+
if (windsurfVars.length > 0) {
|
|
32
|
+
return 'windsurf';
|
|
33
|
+
}
|
|
34
|
+
// VS Code detection (lowest priority - most generic)
|
|
35
|
+
const vscodeVars = Object.keys(process.env).filter((key) => key.startsWith('VSCODE_'));
|
|
36
|
+
if (vscodeVars.length > 0) {
|
|
37
|
+
return 'vscode';
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get command version safely using execFileSync
|
|
43
|
+
*/
|
|
44
|
+
function getCommandVersion(command, args) {
|
|
45
|
+
try {
|
|
46
|
+
const output = execFileSync(command, args, {
|
|
47
|
+
encoding: 'utf-8',
|
|
48
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
49
|
+
}).trim();
|
|
50
|
+
return output;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return 'not found';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse semver version string to compare
|
|
58
|
+
*/
|
|
59
|
+
function parseVersion(versionStr) {
|
|
60
|
+
// WU-1968: Removed ^ anchor so "git version 2.43.0" is parsed correctly.
|
|
61
|
+
// The previous ^v? pattern required the string to start with a digit or "v",
|
|
62
|
+
// but `git --version` returns "git version X.Y.Z" which starts with "git".
|
|
63
|
+
// eslint-disable-next-line security/detect-unsafe-regex -- static semver pattern; no backtracking risk
|
|
64
|
+
const match = /(\d+)\.(\d+)(?:\.(\d+))?/.exec(versionStr);
|
|
65
|
+
if (!match) {
|
|
66
|
+
return [0, 0, 0];
|
|
67
|
+
}
|
|
68
|
+
return [parseInt(match[1], 10), parseInt(match[2], 10), parseInt(match[3] || '0', 10)];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Compare versions: returns true if actual >= required
|
|
72
|
+
*/
|
|
73
|
+
function compareVersions(actual, required) {
|
|
74
|
+
const actualParts = parseVersion(actual);
|
|
75
|
+
const requiredParts = parseVersion(required);
|
|
76
|
+
for (let i = 0; i < 3; i++) {
|
|
77
|
+
if (actualParts[i] > requiredParts[i]) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
if (actualParts[i] < requiredParts[i]) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* WU-1177: Check prerequisite versions
|
|
88
|
+
* Non-blocking - returns results but doesn't fail init
|
|
89
|
+
*/
|
|
90
|
+
export function checkPrerequisites() {
|
|
91
|
+
const nodeVersion = getCommandVersion('node', ['--version']);
|
|
92
|
+
const pnpmVersion = getCommandVersion('pnpm', ['--version']);
|
|
93
|
+
const gitVersion = getCommandVersion('git', ['--version']);
|
|
94
|
+
const requiredNode = '22.0.0';
|
|
95
|
+
const requiredPnpm = '9.0.0';
|
|
96
|
+
const requiredGit = '2.0.0';
|
|
97
|
+
const nodeOk = nodeVersion !== 'not found' && compareVersions(nodeVersion, requiredNode);
|
|
98
|
+
const pnpmOk = pnpmVersion !== 'not found' && compareVersions(pnpmVersion, requiredPnpm);
|
|
99
|
+
const gitOk = gitVersion !== 'not found' && compareVersions(gitVersion, requiredGit);
|
|
100
|
+
return {
|
|
101
|
+
node: {
|
|
102
|
+
passed: nodeOk,
|
|
103
|
+
version: nodeVersion,
|
|
104
|
+
required: `>=${requiredNode}`,
|
|
105
|
+
message: nodeOk ? undefined : `Node.js ${requiredNode}+ required`,
|
|
106
|
+
},
|
|
107
|
+
pnpm: {
|
|
108
|
+
passed: pnpmOk,
|
|
109
|
+
version: pnpmVersion,
|
|
110
|
+
required: `>=${requiredPnpm}`,
|
|
111
|
+
message: pnpmOk ? undefined : `pnpm ${requiredPnpm}+ required`,
|
|
112
|
+
},
|
|
113
|
+
git: {
|
|
114
|
+
passed: gitOk,
|
|
115
|
+
version: gitVersion,
|
|
116
|
+
required: `>=${requiredGit}`,
|
|
117
|
+
message: gitOk ? undefined : `Git ${requiredGit}+ required`,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* WU-1309: Get docs paths based on structure type
|
|
123
|
+
*/
|
|
124
|
+
export function getDocsPath(structure) {
|
|
125
|
+
if (structure === 'simple') {
|
|
126
|
+
return {
|
|
127
|
+
operations: 'docs',
|
|
128
|
+
tasks: 'docs/tasks',
|
|
129
|
+
onboarding: 'docs/_frameworks/lumenflow/agent/onboarding',
|
|
130
|
+
quickRefLink: 'docs/_frameworks/lumenflow/agent/onboarding/quick-ref-commands.md',
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
// arc42 structure
|
|
134
|
+
return {
|
|
135
|
+
operations: 'docs/04-operations',
|
|
136
|
+
tasks: 'docs/04-operations/tasks',
|
|
137
|
+
onboarding: 'docs/04-operations/_frameworks/lumenflow/agent/onboarding',
|
|
138
|
+
quickRefLink: 'docs/04-operations/_frameworks/lumenflow/agent/onboarding/quick-ref-commands.md',
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* WU-1309: Detect existing docs structure or return default
|
|
143
|
+
* Auto-detects arc42 when docs/04-operations or UnsafeAny numbered dir (01-*, 02-*, etc.) exists
|
|
144
|
+
*/
|
|
145
|
+
export function detectDocsStructure(targetDir) {
|
|
146
|
+
const docsDir = path.join(targetDir, 'docs');
|
|
147
|
+
if (!fs.existsSync(docsDir)) {
|
|
148
|
+
return 'simple';
|
|
149
|
+
}
|
|
150
|
+
// Check for arc42 numbered directories (01-*, 02-*, ..., 04-operations, etc.)
|
|
151
|
+
const entries = fs.readdirSync(docsDir);
|
|
152
|
+
const hasNumberedDir = entries.some((entry) => /^\d{2}-/.test(entry));
|
|
153
|
+
if (hasNumberedDir) {
|
|
154
|
+
return 'arc42';
|
|
155
|
+
}
|
|
156
|
+
return 'simple';
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Detect default client from environment
|
|
160
|
+
*/
|
|
161
|
+
export function detectDefaultClient() {
|
|
162
|
+
if (process.env.CLAUDE_PROJECT_DIR || process.env.CLAUDE_CODE) {
|
|
163
|
+
return DEFAULT_CLIENT_CLAUDE;
|
|
164
|
+
}
|
|
165
|
+
return 'none';
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* WU-1364: Check if directory is a git repository
|
|
169
|
+
*/
|
|
170
|
+
export function isGitRepo(targetDir) {
|
|
171
|
+
try {
|
|
172
|
+
// eslint-disable-next-line sonarjs/no-os-command-from-path -- git resolved from PATH; CLI tool requires git
|
|
173
|
+
execFileSync('git', ['rev-parse', '--git-dir'], {
|
|
174
|
+
cwd: targetDir,
|
|
175
|
+
stdio: 'pipe',
|
|
176
|
+
});
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* WU-1364: Check if git repo has UnsafeAny commits
|
|
185
|
+
*/
|
|
186
|
+
export function hasGitCommits(targetDir) {
|
|
187
|
+
try {
|
|
188
|
+
// eslint-disable-next-line sonarjs/no-os-command-from-path -- git resolved from PATH; CLI tool requires git
|
|
189
|
+
execFileSync('git', ['rev-parse', 'HEAD'], {
|
|
190
|
+
cwd: targetDir,
|
|
191
|
+
stdio: 'pipe',
|
|
192
|
+
});
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* WU-1364: Check if git repo has an origin remote
|
|
201
|
+
*/
|
|
202
|
+
export function hasOriginRemote(targetDir) {
|
|
203
|
+
try {
|
|
204
|
+
// eslint-disable-next-line sonarjs/no-os-command-from-path -- git resolved from PATH; CLI tool requires git
|
|
205
|
+
const result = execFileSync('git', ['remote', 'get-url', 'origin'], {
|
|
206
|
+
cwd: targetDir,
|
|
207
|
+
encoding: 'utf-8',
|
|
208
|
+
stdio: 'pipe',
|
|
209
|
+
});
|
|
210
|
+
return result.trim().length > 0;
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* WU-1364: Detect git state and return config overrides
|
|
218
|
+
* Returns requireRemote: false if no origin remote is configured
|
|
219
|
+
*/
|
|
220
|
+
export function detectGitStateConfig(targetDir) {
|
|
221
|
+
// If not a git repo, default to local-only mode for safety
|
|
222
|
+
if (!isGitRepo(targetDir)) {
|
|
223
|
+
return { requireRemote: false };
|
|
224
|
+
}
|
|
225
|
+
// If git repo but no origin remote, set requireRemote: false
|
|
226
|
+
if (!hasOriginRemote(targetDir)) {
|
|
227
|
+
return { requireRemote: false };
|
|
228
|
+
}
|
|
229
|
+
// Has origin remote - use default (requireRemote: true)
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=init-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-detection.js","sourceRoot":"","sources":["../src/init-detection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* @file init-lane-validation.ts
|
|
5
|
+
* Lane config validation against inference hierarchy.
|
|
6
|
+
*
|
|
7
|
+
* WU-1745: Validate lane config against inference hierarchy at init time
|
|
8
|
+
*
|
|
9
|
+
* Cross-checks lane definitions in workspace.yaml software_delivery against
|
|
10
|
+
* .lumenflow.lane-inference.yaml parents. Catches invalid parent names
|
|
11
|
+
* (e.g., "Foundation: Core" when "Foundation" is not a valid parent)
|
|
12
|
+
* at init time instead of deferring to wu:create.
|
|
13
|
+
*/
|
|
14
|
+
import * as fs from 'node:fs';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
import * as yaml from 'yaml';
|
|
17
|
+
import { WORKSPACE_CONFIG_FILE_NAME } from '@lumenflow/core/config';
|
|
18
|
+
import { WORKSPACE_V2_KEYS } from '@lumenflow/core/config-schema';
|
|
19
|
+
/** Separator between parent and sublane in lane names */
|
|
20
|
+
const LANE_NAME_SEPARATOR = ': ';
|
|
21
|
+
const SOFTWARE_DELIVERY_KEY = WORKSPACE_V2_KEYS.SOFTWARE_DELIVERY;
|
|
22
|
+
/**
|
|
23
|
+
* Extract the parent name from a "Parent: Sublane" lane name.
|
|
24
|
+
*
|
|
25
|
+
* @param laneName - Lane name in "Parent: Sublane" format
|
|
26
|
+
* @returns The parent portion, or null if no separator found
|
|
27
|
+
*/
|
|
28
|
+
function extractParentName(laneName) {
|
|
29
|
+
const separatorIndex = laneName.indexOf(LANE_NAME_SEPARATOR);
|
|
30
|
+
if (separatorIndex === -1) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return laneName.substring(0, separatorIndex);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Validate lane definitions from config against valid inference hierarchy parents.
|
|
37
|
+
*
|
|
38
|
+
* Checks that each lane's parent (the part before ": ") exists as a top-level
|
|
39
|
+
* key in the lane inference hierarchy.
|
|
40
|
+
*
|
|
41
|
+
* @param configLanes - Lane definitions from workspace.yaml software_delivery
|
|
42
|
+
* @param inferenceParents - Valid parent names from .lumenflow.lane-inference.yaml
|
|
43
|
+
* @returns Validation result with warnings and invalid lane names
|
|
44
|
+
*/
|
|
45
|
+
export function validateLaneConfigAgainstInference(configLanes, inferenceParents) {
|
|
46
|
+
const warnings = [];
|
|
47
|
+
const invalidLanes = [];
|
|
48
|
+
if (configLanes.length === 0) {
|
|
49
|
+
return { warnings, invalidLanes };
|
|
50
|
+
}
|
|
51
|
+
const validParentSet = new Set(inferenceParents);
|
|
52
|
+
for (const lane of configLanes) {
|
|
53
|
+
const parent = extractParentName(lane.name);
|
|
54
|
+
if (parent === null) {
|
|
55
|
+
// Lane name doesn't use "Parent: Sublane" format
|
|
56
|
+
warnings.push(`Lane "${lane.name}" does not use the required "Parent: Sublane" format. ` +
|
|
57
|
+
`Valid parent names: ${inferenceParents.join(', ')}`);
|
|
58
|
+
invalidLanes.push(lane.name);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (!validParentSet.has(parent)) {
|
|
62
|
+
warnings.push(`Lane "${lane.name}" uses invalid parent "${parent}". ` +
|
|
63
|
+
`Valid parent names in lane-inference hierarchy: ${inferenceParents.join(', ')}`);
|
|
64
|
+
invalidLanes.push(lane.name);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { warnings, invalidLanes };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Extract top-level parent names from a lane inference YAML file.
|
|
71
|
+
*
|
|
72
|
+
* The lane inference file uses hierarchical format:
|
|
73
|
+
* Parent:
|
|
74
|
+
* Sublane:
|
|
75
|
+
* code_paths: [...]
|
|
76
|
+
*
|
|
77
|
+
* This function returns the top-level keys (parent names).
|
|
78
|
+
*
|
|
79
|
+
* @param laneInferencePath - Path to .lumenflow.lane-inference.yaml
|
|
80
|
+
* @returns Array of parent names, or empty array if file doesn't exist/is invalid
|
|
81
|
+
*/
|
|
82
|
+
export function extractInferenceParents(laneInferencePath) {
|
|
83
|
+
if (!fs.existsSync(laneInferencePath)) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const content = fs.readFileSync(laneInferencePath, 'utf-8');
|
|
88
|
+
const parsed = yaml.parse(content);
|
|
89
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
// Top-level keys are parent names
|
|
93
|
+
return Object.keys(parsed);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Extract lane definitions from a workspace YAML file.
|
|
101
|
+
*
|
|
102
|
+
* @param configPath - Path to workspace.yaml
|
|
103
|
+
* @returns Array of lane definitions, or empty array if not found
|
|
104
|
+
*/
|
|
105
|
+
export function extractConfigLanes(configPath) {
|
|
106
|
+
if (!fs.existsSync(configPath)) {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
111
|
+
const parsed = yaml.parse(content);
|
|
112
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
const softwareDelivery = parsed[SOFTWARE_DELIVERY_KEY];
|
|
116
|
+
const lanes = softwareDelivery?.lanes;
|
|
117
|
+
const definitions = lanes?.definitions;
|
|
118
|
+
if (!Array.isArray(definitions)) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
return definitions;
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Run lane validation for a project directory.
|
|
129
|
+
*
|
|
130
|
+
* Reads both workspace.yaml and .lumenflow.lane-inference.yaml,
|
|
131
|
+
* then validates that all lane parents exist in the inference hierarchy.
|
|
132
|
+
*
|
|
133
|
+
* @param targetDir - Project root directory
|
|
134
|
+
* @returns Validation result with warnings and invalid lane names
|
|
135
|
+
*/
|
|
136
|
+
export function validateLanesForProject(targetDir) {
|
|
137
|
+
const configPath = path.join(targetDir, WORKSPACE_CONFIG_FILE_NAME);
|
|
138
|
+
const inferencePath = path.join(targetDir, '.lumenflow.lane-inference.yaml');
|
|
139
|
+
const configLanes = extractConfigLanes(configPath);
|
|
140
|
+
const inferenceParents = extractInferenceParents(inferencePath);
|
|
141
|
+
// If either file is missing or empty, skip validation
|
|
142
|
+
if (configLanes.length === 0 || inferenceParents.length === 0) {
|
|
143
|
+
return { warnings: [], invalidLanes: [] };
|
|
144
|
+
}
|
|
145
|
+
return validateLaneConfigAgainstInference(configLanes, inferenceParents);
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=init-lane-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-lane-validation.js","sourceRoot":"","sources":["../src/init-lane-validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* @file init-scaffolding.ts
|
|
5
|
+
* File-system scaffolding helpers for LumenFlow init command (WU-1644)
|
|
6
|
+
*
|
|
7
|
+
* Extracted from init.ts -- file creation, directory creation,
|
|
8
|
+
* template loading/processing, and merge-mode handling.
|
|
9
|
+
*/
|
|
10
|
+
import * as fs from 'node:fs';
|
|
11
|
+
import * as path from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
// WU-1171: Import merge block utilities
|
|
14
|
+
import { updateMergeBlock } from './merge-block.js';
|
|
15
|
+
/**
|
|
16
|
+
* Process template content by replacing placeholders
|
|
17
|
+
*/
|
|
18
|
+
export function processTemplate(content, tokens) {
|
|
19
|
+
let output = content;
|
|
20
|
+
for (const [key, value] of Object.entries(tokens)) {
|
|
21
|
+
// eslint-disable-next-line security/detect-non-literal-regexp -- key is from internal token map, not user input
|
|
22
|
+
output = output.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), value);
|
|
23
|
+
}
|
|
24
|
+
return output;
|
|
25
|
+
}
|
|
26
|
+
export function getRelativePath(targetDir, filePath) {
|
|
27
|
+
return path.relative(targetDir, filePath).split(path.sep).join('/');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* WU-1171: Get templates directory path
|
|
31
|
+
*/
|
|
32
|
+
export function getTemplatesDir() {
|
|
33
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
34
|
+
const __dirname = path.dirname(__filename);
|
|
35
|
+
// Check for dist/templates (production) or ../templates (development)
|
|
36
|
+
const distTemplates = path.join(__dirname, '..', 'templates');
|
|
37
|
+
if (fs.existsSync(distTemplates)) {
|
|
38
|
+
return distTemplates;
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Templates directory not found at ${distTemplates}`);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* WU-1171: Load a template file
|
|
44
|
+
*/
|
|
45
|
+
export function loadTemplate(templatePath) {
|
|
46
|
+
const templatesDir = getTemplatesDir();
|
|
47
|
+
const fullPath = path.join(templatesDir, templatePath);
|
|
48
|
+
if (!fs.existsSync(fullPath)) {
|
|
49
|
+
throw new Error(`Template not found: ${templatePath}`);
|
|
50
|
+
}
|
|
51
|
+
return fs.readFileSync(fullPath, 'utf-8');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Convert boolean or FileMode to FileMode
|
|
55
|
+
*/
|
|
56
|
+
export function resolveBooleanToFileMode(mode) {
|
|
57
|
+
if (typeof mode === 'boolean') {
|
|
58
|
+
return mode ? 'force' : 'skip';
|
|
59
|
+
}
|
|
60
|
+
return mode;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Handle merge mode file update
|
|
64
|
+
*/
|
|
65
|
+
export function handleMergeMode(filePath, content, result, relativePath) {
|
|
66
|
+
const existingContent = fs.readFileSync(filePath, 'utf-8');
|
|
67
|
+
const mergeResult = updateMergeBlock(existingContent, content);
|
|
68
|
+
if (mergeResult.unchanged) {
|
|
69
|
+
result.skipped.push(relativePath);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (mergeResult.warning) {
|
|
73
|
+
result.warnings?.push(`${relativePath}: ${mergeResult.warning}`);
|
|
74
|
+
}
|
|
75
|
+
fs.writeFileSync(filePath, mergeResult.content);
|
|
76
|
+
result.merged?.push(relativePath);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Write a new file, creating parent directories if needed
|
|
80
|
+
*/
|
|
81
|
+
export function writeNewFile(filePath, content, result, relativePath) {
|
|
82
|
+
const parentDir = path.dirname(filePath);
|
|
83
|
+
if (!fs.existsSync(parentDir)) {
|
|
84
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
fs.writeFileSync(filePath, content);
|
|
87
|
+
result.created.push(relativePath);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Create a directory if missing
|
|
91
|
+
*/
|
|
92
|
+
export async function createDirectory(dirPath, result, targetDir) {
|
|
93
|
+
if (!fs.existsSync(dirPath)) {
|
|
94
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
95
|
+
result.created.push(getRelativePath(targetDir, dirPath));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* WU-1171: Create a file with support for skip, merge, and force modes
|
|
100
|
+
*
|
|
101
|
+
* @param filePath - Path to the file to create
|
|
102
|
+
* @param content - Content to write (or merge block content in merge mode)
|
|
103
|
+
* @param mode - 'skip' (default), 'merge', or 'force'
|
|
104
|
+
* @param result - ScaffoldResult to track created/skipped/merged files
|
|
105
|
+
* @param targetDir - Target directory for relative path calculation
|
|
106
|
+
*/
|
|
107
|
+
export async function createFile(filePath, content, mode, result, targetDir) {
|
|
108
|
+
const relativePath = getRelativePath(targetDir, filePath);
|
|
109
|
+
// Handle boolean for backwards compatibility (true = force, false = skip)
|
|
110
|
+
const resolvedMode = resolveBooleanToFileMode(mode);
|
|
111
|
+
// Ensure merged/warnings/overwritten arrays exist
|
|
112
|
+
result.merged = result.merged ?? [];
|
|
113
|
+
result.warnings = result.warnings ?? [];
|
|
114
|
+
result.overwritten = result.overwritten ?? [];
|
|
115
|
+
const fileExists = fs.existsSync(filePath);
|
|
116
|
+
if (fileExists && resolvedMode === 'skip') {
|
|
117
|
+
result.skipped.push(relativePath);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (fileExists && resolvedMode === 'merge') {
|
|
121
|
+
handleMergeMode(filePath, content, result, relativePath);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// WU-1965: Track overwritten files when force mode replaces an existing file
|
|
125
|
+
if (fileExists && resolvedMode === 'force') {
|
|
126
|
+
result.overwritten.push(relativePath);
|
|
127
|
+
}
|
|
128
|
+
// Force mode or file doesn't exist: write new content
|
|
129
|
+
writeNewFile(filePath, content, result, relativePath);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* WU-1394: Create an executable script file with proper permissions
|
|
133
|
+
* Similar to createFile but sets 0o755 mode for shell scripts
|
|
134
|
+
*/
|
|
135
|
+
export async function createExecutableScript(filePath, content, mode, result, targetDir) {
|
|
136
|
+
const relativePath = getRelativePath(targetDir, filePath);
|
|
137
|
+
const resolvedMode = resolveBooleanToFileMode(mode);
|
|
138
|
+
result.merged = result.merged ?? [];
|
|
139
|
+
result.warnings = result.warnings ?? [];
|
|
140
|
+
result.overwritten = result.overwritten ?? [];
|
|
141
|
+
const fileExists = fs.existsSync(filePath);
|
|
142
|
+
if (fileExists && resolvedMode === 'skip') {
|
|
143
|
+
result.skipped.push(relativePath);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
// WU-1965: Track overwritten files
|
|
147
|
+
if (fileExists && (resolvedMode === 'force' || resolvedMode === 'merge')) {
|
|
148
|
+
result.overwritten.push(relativePath);
|
|
149
|
+
}
|
|
150
|
+
// Write file with executable permissions
|
|
151
|
+
const parentDir = path.dirname(filePath);
|
|
152
|
+
if (!fs.existsSync(parentDir)) {
|
|
153
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
154
|
+
}
|
|
155
|
+
fs.writeFileSync(filePath, content, { mode: 0o755 });
|
|
156
|
+
result.created.push(relativePath);
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=init-scaffolding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-scaffolding.js","sourceRoot":"","sources":["../src/init-scaffolding.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,yCAAyC;AAEzC;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,wCAAwC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAoBpD;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,MAA8B;IAC7E,IAAI,MAAM,GAAG,OAAO,CAAC;IACrB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,gHAAgH;QAChH,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,SAAS,GAAG,QAAQ,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,QAAgB;IACjE,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAE3C,sEAAsE;IACtE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IAC9D,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACjC,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oCAAoC,aAAa,EAAE,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,YAAoB;IAC/C,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAEvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,uBAAuB,YAAY,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAwB;IAC/D,IAAI,OAAO,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,OAAe,EACf,MAAsB,EACtB,YAAoB;IAEpB,MAAM,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,gBAAgB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAE/D,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,YAAY,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAgB,EAChB,OAAe,EACf,MAAsB,EACtB,YAAoB;IAEpB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,MAAsB,EACtB,SAAiB;IAEjB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,QAAgB,EAChB,OAAe,EACf,IAAwB,EACxB,MAAsB,EACtB,SAAiB;IAEjB,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAE1D,0EAA0E;IAC1E,MAAM,YAAY,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAEpD,kDAAkD;IAClD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IACpC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IACxC,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;IAE9C,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAE3C,IAAI,UAAU,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,IAAI,UAAU,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;QAC3C,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IAED,6EAA6E;IAC7E,IAAI,UAAU,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;QAC3C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC;IAED,sDAAsD;IACtD,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,QAAgB,EAChB,OAAe,EACf,IAAwB,EACxB,MAAsB,EACtB,SAAiB;IAEjB,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAEpD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IACpC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IACxC,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;IAE9C,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAE3C,IAAI,UAAU,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,mCAAmC;IACnC,IAAI,UAAU,IAAI,CAAC,YAAY,KAAK,OAAO,IAAI,YAAY,KAAK,OAAO,CAAC,EAAE,CAAC;QACzE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC;IAED,yCAAyC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACrD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AACpC,CAAC"}
|