bmad-fh 6.0.0-alpha.23 → 6.0.0-alpha.23.3b00cb36
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/.github/workflows/publish.yaml +68 -0
- package/.husky/pre-commit +17 -2
- package/.husky/pre-push +10 -0
- package/README.md +117 -14
- package/eslint.config.mjs +2 -2
- package/package.json +1 -2
- package/src/bmm/module.yaml +2 -2
- package/src/core/lib/scope/artifact-resolver.js +26 -26
- package/src/core/lib/scope/event-logger.js +34 -45
- package/src/core/lib/scope/index.js +3 -3
- package/src/core/lib/scope/scope-context.js +22 -28
- package/src/core/lib/scope/scope-initializer.js +29 -31
- package/src/core/lib/scope/scope-manager.js +57 -24
- package/src/core/lib/scope/scope-migrator.js +44 -52
- package/src/core/lib/scope/scope-sync.js +42 -48
- package/src/core/lib/scope/scope-validator.js +16 -21
- package/src/core/lib/scope/state-lock.js +37 -43
- package/src/core/module.yaml +2 -2
- package/test/test-scope-cli.js +1306 -0
- package/test/test-scope-e2e.js +682 -92
- package/test/test-scope-system.js +973 -169
- package/tools/cli/bmad-cli.js +5 -0
- package/tools/cli/commands/scope.js +1250 -115
- package/tools/cli/installers/lib/modules/manager.js +6 -2
- package/tools/cli/scripts/migrate-workflows.js +43 -51
- package/.github/workflows/publish-multi-artifact.yaml +0 -50
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- feat/multi-artifact-support
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
packages: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
with:
|
|
19
|
+
fetch-depth: 0
|
|
20
|
+
|
|
21
|
+
- name: Setup Node.js
|
|
22
|
+
uses: actions/setup-node@v4
|
|
23
|
+
with:
|
|
24
|
+
node-version-file: ".nvmrc"
|
|
25
|
+
cache: npm
|
|
26
|
+
registry-url: https://registry.npmjs.org
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: npm ci
|
|
30
|
+
|
|
31
|
+
- name: Set version with commit hash
|
|
32
|
+
id: version
|
|
33
|
+
run: |
|
|
34
|
+
BASE_VERSION=$(node -p "require('./package.json').version")
|
|
35
|
+
SHORT_SHA=$(git rev-parse --short HEAD)
|
|
36
|
+
NEW_VERSION="${BASE_VERSION}.${SHORT_SHA}"
|
|
37
|
+
npm version "${NEW_VERSION}" --no-git-tag-version
|
|
38
|
+
echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT
|
|
39
|
+
|
|
40
|
+
- name: Publish to NPM
|
|
41
|
+
env:
|
|
42
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
43
|
+
run: |
|
|
44
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
45
|
+
echo "Checking if bmad-fh@${VERSION} already exists..."
|
|
46
|
+
|
|
47
|
+
# Check if version already exists on npm
|
|
48
|
+
if npm view "bmad-fh@${VERSION}" version 2>/dev/null; then
|
|
49
|
+
echo "Version ${VERSION} already exists on npm, skipping publish"
|
|
50
|
+
echo "SKIPPED=true" >> $GITHUB_ENV
|
|
51
|
+
else
|
|
52
|
+
echo "Publishing bmad-fh@${VERSION}"
|
|
53
|
+
npm publish --ignore-scripts
|
|
54
|
+
echo "SKIPPED=false" >> $GITHUB_ENV
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
- name: Summary
|
|
58
|
+
run: |
|
|
59
|
+
if [ "$SKIPPED" = "true" ]; then
|
|
60
|
+
echo "## Skipped - bmad-fh@${{ steps.version.outputs.version }} already exists" >> $GITHUB_STEP_SUMMARY
|
|
61
|
+
else
|
|
62
|
+
echo "## Published bmad-fh@${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
63
|
+
fi
|
|
64
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
65
|
+
echo "### Installation" >> $GITHUB_STEP_SUMMARY
|
|
66
|
+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
|
|
67
|
+
echo "npx bmad-fh install" >> $GITHUB_STEP_SUMMARY
|
|
68
|
+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
package/.husky/pre-commit
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env sh
|
|
2
2
|
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Call .githooks/pre-commit first (if exists)
|
|
5
|
+
# =============================================================================
|
|
6
|
+
if [ -x ".githooks/pre-commit" ]; then
|
|
7
|
+
.githooks/pre-commit "$@"
|
|
8
|
+
GITHOOKS_EXIT=$?
|
|
9
|
+
if [ $GITHOOKS_EXIT -ne 0 ]; then
|
|
10
|
+
exit $GITHOOKS_EXIT
|
|
11
|
+
fi
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
# =============================================================================
|
|
15
|
+
# Husky-specific: lint-staged and tests
|
|
16
|
+
# =============================================================================
|
|
17
|
+
|
|
3
18
|
# Auto-fix changed files and stage them
|
|
4
19
|
npx --no-install lint-staged
|
|
5
20
|
|
|
@@ -10,11 +25,11 @@ npm test
|
|
|
10
25
|
if command -v rg >/dev/null 2>&1; then
|
|
11
26
|
if git diff --cached --name-only | rg -q '^docs/'; then
|
|
12
27
|
npm run docs:validate-links
|
|
13
|
-
|
|
28
|
+
npm run docs:build
|
|
14
29
|
fi
|
|
15
30
|
else
|
|
16
31
|
if git diff --cached --name-only | grep -Eq '^docs/'; then
|
|
17
32
|
npm run docs:validate-links
|
|
18
|
-
|
|
33
|
+
npm run docs:build
|
|
19
34
|
fi
|
|
20
35
|
fi
|
package/.husky/pre-push
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
|
|
3
|
+
# Delegate to .githooks/pre-push for comprehensive checks
|
|
4
|
+
# (upstream sync, rebase check, single-commit enforcement)
|
|
5
|
+
|
|
6
|
+
if [ -x ".githooks/pre-push" ]; then
|
|
7
|
+
.githooks/pre-push "$@"
|
|
8
|
+
else
|
|
9
|
+
echo "Warning: .githooks/pre-push not found, skipping custom checks"
|
|
10
|
+
fi
|
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Traditional AI tools do the thinking for you, producing average results. BMad ag
|
|
|
23
23
|
**Prerequisites**: [Node.js](https://nodejs.org) v20+
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
npx bmad-fh
|
|
26
|
+
npx bmad-fh install
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Follow the installer prompts to configure your project. Then run:
|
|
@@ -66,31 +66,134 @@ BMad supports running multiple workflows in parallel across different terminal s
|
|
|
66
66
|
- **Multi-team projects** — Each team works in their own scope
|
|
67
67
|
- **Parallel feature development** — Develop auth, payments, and catalog simultaneously
|
|
68
68
|
- **Microservices** — One scope per service with shared contracts
|
|
69
|
+
- **Experimentation** — Create isolated scopes for spikes and prototypes
|
|
70
|
+
|
|
71
|
+
### Quick Start
|
|
69
72
|
|
|
70
73
|
```bash
|
|
71
74
|
# Initialize scope system
|
|
72
|
-
bmad scope init
|
|
75
|
+
npx bmad-fh scope init
|
|
73
76
|
|
|
74
77
|
# Create scopes for different services
|
|
75
|
-
bmad scope create auth --name "Authentication"
|
|
76
|
-
bmad scope create payments --name "
|
|
78
|
+
npx bmad-fh scope create auth --name "Authentication Service"
|
|
79
|
+
npx bmad-fh scope create payments --name "Payment Processing" --deps auth
|
|
80
|
+
|
|
81
|
+
# Set the active scope for your session
|
|
82
|
+
npx bmad-fh scope set auth
|
|
77
83
|
|
|
78
84
|
# Run workflows in parallel (different terminals)
|
|
79
|
-
|
|
80
|
-
|
|
85
|
+
# Terminal 1: Set scope to auth, run agent workflows
|
|
86
|
+
# Terminal 2: Set scope to payments, run agent workflows
|
|
81
87
|
|
|
82
88
|
# Share artifacts between scopes
|
|
83
|
-
bmad scope sync-up auth # Promote to shared layer
|
|
84
|
-
bmad scope sync-down payments # Pull shared updates
|
|
89
|
+
npx bmad-fh scope sync-up auth # Promote to shared layer
|
|
90
|
+
npx bmad-fh scope sync-down payments # Pull shared updates
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### CLI Reference
|
|
94
|
+
|
|
95
|
+
| Command | Description |
|
|
96
|
+
| ---------------------------------- | ------------------------------------------- |
|
|
97
|
+
| `npx bmad-fh scope init` | Initialize the scope system in your project |
|
|
98
|
+
| `npx bmad-fh scope list` | List all scopes (alias: `ls`) |
|
|
99
|
+
| `npx bmad-fh scope create <id>` | Create a new scope (alias: `new`) |
|
|
100
|
+
| `npx bmad-fh scope info <id>` | Show scope details (alias: `show`) |
|
|
101
|
+
| `npx bmad-fh scope set [id]` | Set active scope for session (alias: `use`) |
|
|
102
|
+
| `npx bmad-fh scope unset` | Clear active scope (alias: `clear`) |
|
|
103
|
+
| `npx bmad-fh scope remove <id>` | Remove a scope (aliases: `rm`, `delete`) |
|
|
104
|
+
| `npx bmad-fh scope archive <id>` | Archive a completed scope |
|
|
105
|
+
| `npx bmad-fh scope activate <id>` | Reactivate an archived scope |
|
|
106
|
+
| `npx bmad-fh scope sync-up <id>` | Promote artifacts to shared layer |
|
|
107
|
+
| `npx bmad-fh scope sync-down <id>` | Pull shared updates into scope |
|
|
108
|
+
| `npx bmad-fh scope help [cmd]` | Show help (add command for detailed help) |
|
|
109
|
+
|
|
110
|
+
### Create Options
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npx bmad-fh scope create auth \
|
|
114
|
+
--name "Authentication Service" \
|
|
115
|
+
--description "User auth, SSO, and session management" \
|
|
116
|
+
--deps users,notifications \
|
|
117
|
+
--context # Create scope-specific project-context.md
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Directory Structure
|
|
121
|
+
|
|
122
|
+
After initialization and scope creation:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
project-root/
|
|
126
|
+
├── _bmad/
|
|
127
|
+
│ ├── _config/
|
|
128
|
+
│ │ └── scopes.yaml # Scope registry and settings
|
|
129
|
+
│ └── _events/
|
|
130
|
+
│ ├── event-log.yaml # Event history
|
|
131
|
+
│ └── subscriptions.yaml # Cross-scope subscriptions
|
|
132
|
+
│
|
|
133
|
+
├── _bmad-output/
|
|
134
|
+
│ ├── _shared/ # Shared knowledge layer
|
|
135
|
+
│ │ ├── project-context.md # Global project context
|
|
136
|
+
│ │ ├── contracts/ # Integration contracts
|
|
137
|
+
│ │ └── principles/ # Architecture principles
|
|
138
|
+
│ │
|
|
139
|
+
│ ├── auth/ # Auth scope artifacts
|
|
140
|
+
│ │ ├── planning-artifacts/
|
|
141
|
+
│ │ ├── implementation-artifacts/
|
|
142
|
+
│ │ └── tests/
|
|
143
|
+
│ │
|
|
144
|
+
│ └── payments/ # Payments scope artifacts
|
|
145
|
+
│ └── ...
|
|
146
|
+
│
|
|
147
|
+
└── .bmad-scope # Session-sticky active scope (gitignored)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Access Model
|
|
151
|
+
|
|
152
|
+
Scopes follow a "read-any, write-own" isolation model:
|
|
153
|
+
|
|
154
|
+
| Operation | Own Scope | Other Scopes | \_shared/ |
|
|
155
|
+
| --------- | --------- | ------------ | ----------- |
|
|
156
|
+
| **Read** | Allowed | Allowed | Allowed |
|
|
157
|
+
| **Write** | Allowed | Blocked | via sync-up |
|
|
158
|
+
|
|
159
|
+
### Workflow Integration
|
|
160
|
+
|
|
161
|
+
Workflows (run via agent menus like `CP` for Create PRD, `DS` for Dev Story) automatically detect and use scope context. Resolution order:
|
|
162
|
+
|
|
163
|
+
1. Session context from `.bmad-scope` file (set via `scope set`)
|
|
164
|
+
2. `BMAD_SCOPE` environment variable
|
|
165
|
+
3. Prompt user to select or create scope
|
|
166
|
+
|
|
167
|
+
**Setting your active scope:**
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Set scope for your terminal session
|
|
171
|
+
npx bmad-fh scope set auth
|
|
172
|
+
|
|
173
|
+
# Or use environment variable (useful for CI/CD)
|
|
174
|
+
export BMAD_SCOPE=auth
|
|
85
175
|
```
|
|
86
176
|
|
|
87
|
-
**
|
|
88
|
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
177
|
+
**Scope-aware path variables in workflows:**
|
|
178
|
+
|
|
179
|
+
- `{scope}` → Scope ID (e.g., "auth")
|
|
180
|
+
- `{scope_path}` → `_bmad-output/auth`
|
|
181
|
+
- `{scope_planning}` → `_bmad-output/auth/planning-artifacts`
|
|
182
|
+
- `{scope_implementation}` → `_bmad-output/auth/implementation-artifacts`
|
|
183
|
+
- `{scope_tests}` → `_bmad-output/auth/tests`
|
|
184
|
+
|
|
185
|
+
### Getting Help
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Show comprehensive help for all scope commands
|
|
189
|
+
npx bmad-fh scope help
|
|
190
|
+
|
|
191
|
+
# Get detailed help for a specific command
|
|
192
|
+
npx bmad-fh scope help create
|
|
193
|
+
npx bmad-fh scope help sync-up
|
|
194
|
+
```
|
|
92
195
|
|
|
93
|
-
See [Multi-Scope Guide](docs/multi-scope-guide.md) for
|
|
196
|
+
See [Multi-Scope Guide](docs/multi-scope-guide.md) for complete documentation.
|
|
94
197
|
|
|
95
198
|
## Community
|
|
96
199
|
|
package/eslint.config.mjs
CHANGED
|
@@ -81,9 +81,9 @@ export default [
|
|
|
81
81
|
},
|
|
82
82
|
},
|
|
83
83
|
|
|
84
|
-
// CLI scripts under tools
|
|
84
|
+
// CLI scripts under tools/**, test/**, and src/core/lib/**
|
|
85
85
|
{
|
|
86
|
-
files: ['tools/**/*.js', 'tools/**/*.mjs', 'test/**/*.js'],
|
|
86
|
+
files: ['tools/**/*.js', 'tools/**/*.mjs', 'test/**/*.js', 'src/core/lib/**/*.js'],
|
|
87
87
|
rules: {
|
|
88
88
|
// Allow CommonJS patterns for Node CLI scripts
|
|
89
89
|
'unicorn/prefer-module': 'off',
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "bmad-fh",
|
|
4
|
-
"version": "6.0.0-alpha.23",
|
|
4
|
+
"version": "6.0.0-alpha.23.3b00cb36",
|
|
5
5
|
"description": "Breakthrough Method of Agile AI-driven Development",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"agile",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
26
|
"bmad:install": "node tools/cli/bmad-cli.js install",
|
|
27
|
-
"publish:multi-artifact": "npm publish --tag multi-artifact",
|
|
28
27
|
"bundle": "node tools/cli/bundlers/bundle-web.js all",
|
|
29
28
|
"docs:build": "node tools/build-docs.js",
|
|
30
29
|
"docs:dev": "astro dev --root website",
|
package/src/bmm/module.yaml
CHANGED
|
@@ -34,13 +34,13 @@ user_skill_level:
|
|
|
34
34
|
scope:
|
|
35
35
|
default: ""
|
|
36
36
|
result: "{value}"
|
|
37
|
-
runtime: true
|
|
37
|
+
runtime: true # Indicates this is resolved at runtime, not during install
|
|
38
38
|
|
|
39
39
|
# Scope-aware path helper - resolves to output_folder/scope or just output_folder
|
|
40
40
|
scope_path:
|
|
41
41
|
default: "{output_folder}"
|
|
42
42
|
result: "{value}"
|
|
43
|
-
runtime: true
|
|
43
|
+
runtime: true # Updated at runtime when scope is active
|
|
44
44
|
|
|
45
45
|
planning_artifacts: # Phase 1-3 artifacts
|
|
46
46
|
prompt: "Where should planning artifacts be stored? (Brainstorming, Briefs, PRDs, UX Designs, Architecture, Epics)"
|
|
@@ -3,15 +3,15 @@ const path = require('node:path');
|
|
|
3
3
|
/**
|
|
4
4
|
* Resolves and enforces scope-based artifact access
|
|
5
5
|
* Implements read-any/write-own access model
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* @class ArtifactResolver
|
|
8
|
-
*
|
|
8
|
+
*
|
|
9
9
|
* @example
|
|
10
10
|
* const resolver = new ArtifactResolver({
|
|
11
11
|
* currentScope: 'auth',
|
|
12
12
|
* basePath: '/path/to/_bmad-output'
|
|
13
13
|
* });
|
|
14
|
-
*
|
|
14
|
+
*
|
|
15
15
|
* if (resolver.canWrite('/path/to/_bmad-output/auth/file.md')) {
|
|
16
16
|
* // Write operation allowed
|
|
17
17
|
* }
|
|
@@ -52,7 +52,7 @@ class ArtifactResolver {
|
|
|
52
52
|
extractScopeFromPath(filePath) {
|
|
53
53
|
// Normalize path
|
|
54
54
|
const normalizedPath = path.normalize(filePath);
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
// Find the base path in the file path
|
|
57
57
|
const baseIndex = normalizedPath.indexOf(this.basePath);
|
|
58
58
|
if (baseIndex === -1) {
|
|
@@ -61,16 +61,16 @@ class ArtifactResolver {
|
|
|
61
61
|
|
|
62
62
|
// Get the relative path from base
|
|
63
63
|
const relativePath = normalizedPath.slice(Math.max(0, baseIndex + this.basePath.length + 1));
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
// Split to get the first segment (scope name)
|
|
66
66
|
const segments = relativePath.split(path.sep).filter(Boolean);
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
if (segments.length === 0) {
|
|
69
69
|
return null;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
const firstSegment = segments[0];
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
// Check if it's a reserved path
|
|
75
75
|
if (this.reservedPaths.includes(firstSegment)) {
|
|
76
76
|
return firstSegment; // Return the reserved path name
|
|
@@ -109,7 +109,7 @@ class ArtifactResolver {
|
|
|
109
109
|
// Read is always allowed for all paths
|
|
110
110
|
return {
|
|
111
111
|
allowed: true,
|
|
112
|
-
reason: 'Read access is always allowed in read-any model'
|
|
112
|
+
reason: 'Read access is always allowed in read-any model',
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -124,7 +124,7 @@ class ArtifactResolver {
|
|
|
124
124
|
return {
|
|
125
125
|
allowed: true,
|
|
126
126
|
reason: 'No scope active, operating in legacy mode',
|
|
127
|
-
warning: null
|
|
127
|
+
warning: null,
|
|
128
128
|
};
|
|
129
129
|
}
|
|
130
130
|
|
|
@@ -135,7 +135,7 @@ class ArtifactResolver {
|
|
|
135
135
|
return {
|
|
136
136
|
allowed: false,
|
|
137
137
|
reason: `Cannot write directly to '${this.sharedPath}'. Use: bmad scope sync-up`,
|
|
138
|
-
warning: null
|
|
138
|
+
warning: null,
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
141
|
|
|
@@ -144,7 +144,7 @@ class ArtifactResolver {
|
|
|
144
144
|
return {
|
|
145
145
|
allowed: false,
|
|
146
146
|
reason: `Cannot write to reserved path '${targetScope}'`,
|
|
147
|
-
warning: null
|
|
147
|
+
warning: null,
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -153,7 +153,7 @@ class ArtifactResolver {
|
|
|
153
153
|
return {
|
|
154
154
|
allowed: true,
|
|
155
155
|
reason: `Write allowed to current scope '${this.currentScope}'`,
|
|
156
|
-
warning: null
|
|
156
|
+
warning: null,
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -164,31 +164,31 @@ class ArtifactResolver {
|
|
|
164
164
|
return {
|
|
165
165
|
allowed: false,
|
|
166
166
|
reason: `Cannot write to scope '${targetScope}' while in scope '${this.currentScope}'`,
|
|
167
|
-
warning: null
|
|
167
|
+
warning: null,
|
|
168
168
|
};
|
|
169
169
|
}
|
|
170
|
-
|
|
170
|
+
|
|
171
171
|
case 'warn': {
|
|
172
172
|
return {
|
|
173
173
|
allowed: true,
|
|
174
174
|
reason: 'Write allowed with warning in warn mode',
|
|
175
|
-
warning: `Warning: Writing to scope '${targetScope}' from scope '${this.currentScope}'
|
|
175
|
+
warning: `Warning: Writing to scope '${targetScope}' from scope '${this.currentScope}'`,
|
|
176
176
|
};
|
|
177
177
|
}
|
|
178
|
-
|
|
178
|
+
|
|
179
179
|
case 'permissive': {
|
|
180
180
|
return {
|
|
181
181
|
allowed: true,
|
|
182
182
|
reason: 'Write allowed in permissive mode',
|
|
183
|
-
warning: null
|
|
183
|
+
warning: null,
|
|
184
184
|
};
|
|
185
185
|
}
|
|
186
|
-
|
|
186
|
+
|
|
187
187
|
default: {
|
|
188
188
|
return {
|
|
189
189
|
allowed: false,
|
|
190
190
|
reason: 'Unknown isolation mode',
|
|
191
|
-
warning: null
|
|
191
|
+
warning: null,
|
|
192
192
|
};
|
|
193
193
|
}
|
|
194
194
|
}
|
|
@@ -198,7 +198,7 @@ class ArtifactResolver {
|
|
|
198
198
|
return {
|
|
199
199
|
allowed: true,
|
|
200
200
|
reason: 'Path is outside scope system',
|
|
201
|
-
warning: null
|
|
201
|
+
warning: null,
|
|
202
202
|
};
|
|
203
203
|
}
|
|
204
204
|
|
|
@@ -209,11 +209,11 @@ class ArtifactResolver {
|
|
|
209
209
|
*/
|
|
210
210
|
validateWrite(filePath) {
|
|
211
211
|
const result = this.canWrite(filePath);
|
|
212
|
-
|
|
212
|
+
|
|
213
213
|
if (!result.allowed) {
|
|
214
214
|
throw new Error(result.reason);
|
|
215
215
|
}
|
|
216
|
-
|
|
216
|
+
|
|
217
217
|
if (result.warning) {
|
|
218
218
|
console.warn(result.warning);
|
|
219
219
|
}
|
|
@@ -227,7 +227,7 @@ class ArtifactResolver {
|
|
|
227
227
|
*/
|
|
228
228
|
resolveScopePath(relativePath, scopeId = null) {
|
|
229
229
|
const scope = scopeId || this.currentScope;
|
|
230
|
-
|
|
230
|
+
|
|
231
231
|
if (!scope) {
|
|
232
232
|
// No scope - return path relative to base
|
|
233
233
|
return path.join(this.basePath, relativePath);
|
|
@@ -254,7 +254,7 @@ class ArtifactResolver {
|
|
|
254
254
|
currentScope: this.currentScope ? path.join(this.basePath, this.currentScope) : null,
|
|
255
255
|
shared: path.join(this.basePath, this.sharedPath),
|
|
256
256
|
allScopes: `${this.basePath}/*`,
|
|
257
|
-
description: 'Read access is allowed to all scopes and shared directories'
|
|
257
|
+
description: 'Read access is allowed to all scopes and shared directories',
|
|
258
258
|
};
|
|
259
259
|
}
|
|
260
260
|
|
|
@@ -266,13 +266,13 @@ class ArtifactResolver {
|
|
|
266
266
|
if (!this.currentScope) {
|
|
267
267
|
return {
|
|
268
268
|
all: this.basePath,
|
|
269
|
-
description: 'No scope active - all paths writable (legacy mode)'
|
|
269
|
+
description: 'No scope active - all paths writable (legacy mode)',
|
|
270
270
|
};
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
return {
|
|
274
274
|
currentScope: path.join(this.basePath, this.currentScope),
|
|
275
|
-
description: `Write access limited to scope '${this.currentScope}'
|
|
275
|
+
description: `Write access limited to scope '${this.currentScope}'`,
|
|
276
276
|
};
|
|
277
277
|
}
|
|
278
278
|
|