@ryuenn3123/agentic-senior-core 3.0.0 → 3.0.3
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/.agent-context/prompts/bootstrap-design.md +22 -0
- package/.agent-context/prompts/init-project.md +50 -34
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.cursorrules +1 -1
- package/.windsurfrules +1 -1
- package/README.md +9 -52
- package/lib/cli/commands/upgrade.mjs +46 -5
- package/lib/cli/utils.mjs +208 -1
- package/package.json +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
# Bootstrap DESIGN.md (UI/UX Art Direction)
|
|
3
|
+
|
|
4
|
+
When a user requests frontend design or redesign, the agent should automatically synthesize a complete DESIGN.md covering:
|
|
5
|
+
- Visual identity (color palette, typography, spacing, iconography)
|
|
6
|
+
- Layout and navigation principles
|
|
7
|
+
- Component library and atomic design system
|
|
8
|
+
- Accessibility and responsive guidelines
|
|
9
|
+
- User journey and interaction flows
|
|
10
|
+
- Design tokens and handoff notes for developers
|
|
11
|
+
|
|
12
|
+
The agent must:
|
|
13
|
+
1. Read [AGENTS.md](../../AGENTS.md) for project context and team roles.
|
|
14
|
+
2. Scan all files in [.agent-context/rules/](../rules/) for UI/UX and accessibility standards.
|
|
15
|
+
3. Reference [docs/deep-dive.md](../../docs/deep-dive.md) and [docs/faq.md](../../docs/faq.md) for architecture and product background.
|
|
16
|
+
4. If [docs/DESIGN.md](../../docs/DESIGN.md) exists, check for drift and propose improvements instead of rewriting from scratch.
|
|
17
|
+
5. All references to docs or rules must be clickable markdown links.
|
|
18
|
+
|
|
19
|
+
Output:
|
|
20
|
+
- Write a full DESIGN.md in markdown, with clear sections and clickable links to referenced docs/rules.
|
|
21
|
+
- Use practical, modern, and accessible design language.
|
|
22
|
+
- Wait for user approval before generating Figma or code assets.
|
|
@@ -1,7 +1,41 @@
|
|
|
1
|
-
# Prompts: Initialize Project
|
|
2
1
|
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
# Project Initialization Prompts
|
|
3
|
+
|
|
4
|
+
This prompt boots a repository with strict rules operations context (Federated Governance baseline).
|
|
5
|
+
|
|
6
|
+
When a new project is created or initialized, the agent should automatically:
|
|
7
|
+
1. Read [AGENTS.md](../../AGENTS.md) to understand available roles and knowledge base.
|
|
8
|
+
2. Scan all files in [.agent-context/rules/](../rules/) for mandatory engineering standards.
|
|
9
|
+
3. Review dynamic stack and architecture signals from [docs/deep-dive.md](../../docs/deep-dive.md), [docs/faq.md](../../docs/faq.md), and task constraints.
|
|
10
|
+
|
|
11
|
+
## Architect Mode (Recommended)
|
|
12
|
+
If the user describes a project or feature, the agent should:
|
|
13
|
+
1. Propose the most efficient technology stack based on requirements and evidence.
|
|
14
|
+
2. Explain why this stack is the best choice for the project.
|
|
15
|
+
3. Draft a high-level architecture plan.
|
|
16
|
+
4. Wait for user approval before scaffolding the project using the selected architecture playbook.
|
|
17
|
+
|
|
18
|
+
## Direct Blueprint Mode
|
|
19
|
+
If the user specifies a framework/blueprint, the agent should:
|
|
20
|
+
1. Read [AGENTS.md](../../AGENTS.md) for role context.
|
|
21
|
+
2. Scan all files in [.agent-context/rules/](../rules/) for engineering standards.
|
|
22
|
+
3. Reference [docs/deep-dive.md](../../docs/deep-dive.md) and [docs/faq.md](../../docs/faq.md) for stack/blueprint guidance.
|
|
23
|
+
4. Scaffold the initial project structure following the blueprint exactly:
|
|
24
|
+
- Create all directories and files from the blueprint
|
|
25
|
+
- Set up environment config and validation (e.g., Zod, Pydantic, FluentValidation)
|
|
26
|
+
- Set up error handling foundation (base error class + global handler)
|
|
27
|
+
- Set up the logger
|
|
28
|
+
- Create a health check endpoint
|
|
29
|
+
- Initialize the ORM/Database connection
|
|
30
|
+
- Every file must follow [naming conventions](../rules/naming-conv.md)
|
|
31
|
+
- Every module must follow [architecture.md](../rules/architecture.md)
|
|
32
|
+
- Every dependency must be justified per [efficiency-vs-hype.md](../rules/efficiency-vs-hype.md)
|
|
33
|
+
|
|
34
|
+
## Stacks & Blueprints Reference
|
|
35
|
+
See [docs/roadmap.md](../../docs/roadmap.md) and [docs/deep-dive.md](../../docs/deep-dive.md) for the latest stack and blueprint list.
|
|
36
|
+
|
|
37
|
+
## UI/UX Bootstrap
|
|
38
|
+
When a user requests frontend or UI/UX design, the agent should automatically execute the [bootstrap-design.md](./bootstrap-design.md) prompt to synthesize DESIGN.md.
|
|
5
39
|
|
|
6
40
|
---
|
|
7
41
|
|
|
@@ -49,38 +83,20 @@ Now scaffold the initial project structure following the blueprint exactly:
|
|
|
49
83
|
- Create a health check endpoint
|
|
50
84
|
- Initialize the ORM/Database connection
|
|
51
85
|
|
|
52
|
-
|
|
53
|
-
Every
|
|
54
|
-
Every
|
|
86
|
+
|
|
87
|
+
Every file must follow [naming conventions](../rules/naming-conv.md).
|
|
88
|
+
Every module must follow [architecture.md](../rules/architecture.md).
|
|
89
|
+
Every dependency must be justified per [efficiency-vs-hype.md](../rules/efficiency-vs-hype.md).
|
|
55
90
|
```
|
|
56
91
|
|
|
57
92
|
---
|
|
58
93
|
|
|
59
|
-
##
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- `
|
|
68
|
-
- `rust`
|
|
69
|
-
- `ruby`
|
|
70
|
-
|
|
71
|
-
### Blueprints (`[BLUEPRINT].md`)
|
|
72
|
-
| Blueprint | Use When |
|
|
73
|
-
|-----------|----------|
|
|
74
|
-
| `api-nextjs` | Next.js App Router API project |
|
|
75
|
-
| `nestjs-logic` | NestJS backend service |
|
|
76
|
-
| `fastapi-service` | Python FastAPI backend service |
|
|
77
|
-
| `laravel-api` | PHP Laravel 13 API |
|
|
78
|
-
| `spring-boot-api`| Java Spring Boot 4 API |
|
|
79
|
-
| `go-service` | Go chi HTTP service |
|
|
80
|
-
| `aspnet-api` | C# ASP.NET Minimal API |
|
|
81
|
-
| `ci-github-actions`| GitHub Actions CI/CD pipeline |
|
|
82
|
-
| `ci-gitlab` | GitLab CI/CD pipeline |
|
|
83
|
-
| `observability` | OpenTelemetry stack |
|
|
84
|
-
| `graphql-grpc-api` | GraphQL / gRPC API definitions |
|
|
85
|
-
| `infrastructure-as-code` | Infrastructure as Code (Terraform | Pulumi) |
|
|
86
|
-
| `kubernetes-manifests` | Kubernetes manifests structure |
|
|
94
|
+
## Stacks & Blueprints Reference
|
|
95
|
+
|
|
96
|
+
See [docs/roadmap.md](../../docs/roadmap.md) and [docs/deep-dive.md](../../docs/deep-dive.md) for the latest stack and blueprint list.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Bootstrap UI/UX (DESIGN.md)
|
|
101
|
+
|
|
102
|
+
To start UI/UX design from scratch, use the [bootstrap-design.md](./bootstrap-design.md) prompt to synthesize `docs/DESIGN.md`.
|
package/.cursorrules
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTIC-SENIOR-CORE DYNAMIC GOVERNANCE RULESET
|
|
2
2
|
|
|
3
|
-
Generated by Agentic-Senior-Core CLI v3.0.
|
|
3
|
+
Generated by Agentic-Senior-Core CLI v3.0.3
|
|
4
4
|
Timestamp: 2026-04-18T00:00:00.000Z
|
|
5
5
|
Selected profile: beginner
|
|
6
6
|
Selected policy file: .agent-context/policies/llm-judge-threshold.json
|
package/.windsurfrules
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTIC-SENIOR-CORE DYNAMIC GOVERNANCE RULESET
|
|
2
2
|
|
|
3
|
-
Generated by Agentic-Senior-Core CLI v3.0.
|
|
3
|
+
Generated by Agentic-Senior-Core CLI v3.0.3
|
|
4
4
|
Timestamp: 2026-04-18T00:00:00.000Z
|
|
5
5
|
Selected profile: beginner
|
|
6
6
|
Selected policy file: .agent-context/policies/llm-judge-threshold.json
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
**Production-grade Rules Engine (Governance Engine) for AI coding agents.**
|
|
11
11
|
Works with Cursor, Windsurf, GitHub Copilot, Claude Code, Gemini, and other LLM-powered IDE workflows.
|
|
12
12
|
|
|
13
|
-
Latest release: 3.0.
|
|
13
|
+
Latest release: 3.0.3 (2026-04-18).
|
|
14
14
|
|
|
15
15
|
Highlights in 3.0.0:
|
|
16
16
|
- Universal IDE adapter surface is completed and synchronized through thin adapters.
|
|
@@ -21,63 +21,17 @@ Highlights in 3.0.0:
|
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
-
## 60-Second Start
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npx @ryuenn3123/agentic-senior-core init
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
That one command initializes your project with compiled rules, review checklists, and state context.
|
|
31
|
-
|
|
32
|
-
Golden Standard mode is now the default path: init applies the recommended quality profile automatically, without a beginner/balanced/strict prompt on first run.
|
|
33
|
-
|
|
34
|
-
Optional team default path:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
npx @ryuenn3123/agentic-senior-core init --profile-pack startup
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Project-description-first path (AI as Architect with veto control):
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
npx @ryuenn3123/agentic-senior-core init --project-description "Machine learning API for fraud detection"
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Default init path now attempts trusted realtime stack research first (with automatic snapshot fallback):
|
|
47
24
|
|
|
48
|
-
|
|
49
|
-
npx @ryuenn3123/agentic-senior-core init --project-description "Event-driven payments platform"
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Force deterministic snapshot-only mode:
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
npx @ryuenn3123/agentic-senior-core init --project-description "Event-driven payments platform" --architect-research-mode snapshot
|
|
56
|
-
```
|
|
25
|
+
## 60-Second Start
|
|
57
26
|
|
|
58
|
-
Optional trusted realtime enrichment (explicitly gated):
|
|
59
27
|
|
|
60
28
|
```bash
|
|
61
|
-
npx @ryuenn3123/agentic-senior-core init
|
|
29
|
+
npx @ryuenn3123/agentic-senior-core init
|
|
62
30
|
```
|
|
63
31
|
|
|
64
|
-
|
|
32
|
+
One command to initialize rules, checklists, and strict AI coding guidelines context for your project.
|
|
65
33
|
|
|
66
|
-
-
|
|
67
|
-
- On first IDE chat, execute `bootstrap-project-context.md` when `docs/project-brief.md` is missing.
|
|
68
|
-
- For UI-first projects, execute `bootstrap-design.md` when `docs/DESIGN.md` is missing.
|
|
69
|
-
- The assistant should synthesize docs from scratch into `docs/` and treat them as living context.
|
|
70
|
-
|
|
71
|
-
Canonical instruction output (multi-tool bridge):
|
|
72
|
-
|
|
73
|
-
- Init now generates `.agent-instructions.md` as canonical instruction source.
|
|
74
|
-
- Init also syncs adapter files for tool compatibility: `.cursorrules`, `.windsurfrules`, `.clauderc`, `.gemini/instructions.md`, and `.github/copilot-instructions.md`.
|
|
75
|
-
|
|
76
|
-
V3 purge readiness dry-run (no deletion):
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
npm run audit:v3-purge
|
|
80
|
-
```
|
|
34
|
+
> **See [docs/deep-dive.md](docs/deep-dive.md) and [docs/roadmap.md](docs/roadmap.md) for advanced configuration, architect mode, snapshot, and realtime options.**
|
|
81
35
|
|
|
82
36
|
- This command writes `.agent-context/state/v3-purge-audit.json` and reports whether static directory deletion is safe.
|
|
83
37
|
|
|
@@ -119,7 +73,7 @@ If you see `Property $schema is not allowed`, keep `.vscode/mcp.json` without `$
|
|
|
119
73
|
|
|
120
74
|
| Command | Purpose |
|
|
121
75
|
|---------|---------|
|
|
122
|
-
| `agentic-senior-core init` | Initialize
|
|
76
|
+
| `agentic-senior-core init` | Initialize strict AI coding guidelines (Federated Governance baseline) |
|
|
123
77
|
| `agentic-senior-core upgrade --dry-run` | Preview safe upgrades |
|
|
124
78
|
| `agentic-senior-core optimize --show` | Show token optimization state |
|
|
125
79
|
| `npm run audit:v3-purge` | Run deep purge readiness audit (no deletion) |
|
|
@@ -136,6 +90,9 @@ npx @ryuenn3123/agentic-senior-core upgrade --yes
|
|
|
136
90
|
|
|
137
91
|
Use `--dry-run` first to preview changes safely, then apply with `--yes`.
|
|
138
92
|
|
|
93
|
+
Upgrade now performs managed-surface synchronization by default: obsolete governance files under managed paths are pruned so the pack stays aligned with the latest release.
|
|
94
|
+
Use `--no-prune` if you want to keep legacy managed files.
|
|
95
|
+
|
|
139
96
|
---
|
|
140
97
|
|
|
141
98
|
## Terminology Mapping (Final)
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
collectFileNames,
|
|
22
22
|
formatDuration,
|
|
23
23
|
pathExists,
|
|
24
|
+
analyzeManagedGovernanceSurface,
|
|
24
25
|
copyGovernanceAssetsToTarget,
|
|
25
26
|
} from '../utils.mjs';
|
|
26
27
|
|
|
@@ -46,7 +47,8 @@ export function parseUpgradeArguments(commandArguments) {
|
|
|
46
47
|
targetDirectory: '.',
|
|
47
48
|
dryRun: false,
|
|
48
49
|
skipConfirmation: false,
|
|
49
|
-
includeMcpTemplate:
|
|
50
|
+
includeMcpTemplate: true,
|
|
51
|
+
pruneManagedSurface: true,
|
|
50
52
|
};
|
|
51
53
|
|
|
52
54
|
for (let argumentIndex = 0; argumentIndex < commandArguments.length; argumentIndex++) {
|
|
@@ -72,6 +74,21 @@ export function parseUpgradeArguments(commandArguments) {
|
|
|
72
74
|
continue;
|
|
73
75
|
}
|
|
74
76
|
|
|
77
|
+
if (currentArgument === '--no-mcp-template') {
|
|
78
|
+
parsedUpgradeOptions.includeMcpTemplate = false;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (currentArgument === '--prune') {
|
|
83
|
+
parsedUpgradeOptions.pruneManagedSurface = true;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (currentArgument === '--no-prune') {
|
|
88
|
+
parsedUpgradeOptions.pruneManagedSurface = false;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
|
|
75
92
|
throw new Error(`Unknown option: ${currentArgument}`);
|
|
76
93
|
}
|
|
77
94
|
|
|
@@ -112,9 +129,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
112
129
|
console.log(`\nAgentic-Senior-Core CLI v${CLI_VERSION}`);
|
|
113
130
|
console.log('Running rules operations upgrade assistant (Federated Governance baseline) for an existing repository.');
|
|
114
131
|
|
|
115
|
-
await
|
|
116
|
-
includeMcpTemplate: upgradeOptions.includeMcpTemplate === true,
|
|
117
|
-
});
|
|
132
|
+
const managedSurfacePlan = await analyzeManagedGovernanceSurface(resolvedTargetDirectoryPath);
|
|
118
133
|
|
|
119
134
|
const stackFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'stacks'));
|
|
120
135
|
const blueprintFileNames = await collectFileNames(path.join(AGENT_CONTEXT_DIR, 'blueprints'));
|
|
@@ -239,12 +254,30 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
239
254
|
console.log(`- Existing rules lines: ${currentRuleLineCount}`);
|
|
240
255
|
console.log(`- Planned rules lines: ${plannedRuleLineCount}`);
|
|
241
256
|
console.log(`- Rules changed: ${isRulesContentChanged ? 'yes' : 'no'}`);
|
|
257
|
+
console.log(`- Managed surface stale files: ${managedSurfacePlan.staleFiles.length}`);
|
|
258
|
+
console.log(`- Managed surface stale directories: ${managedSurfacePlan.staleDirectories.length}`);
|
|
259
|
+
console.log(`- Managed surface prune mode: ${upgradeOptions.pruneManagedSurface === true ? 'enabled (default)' : 'disabled (--no-prune)'}`);
|
|
260
|
+
console.log(`- MCP config write mode: ${upgradeOptions.includeMcpTemplate === true ? 'enabled (default)' : 'disabled (--no-mcp-template)'}`);
|
|
242
261
|
if (projectDocStalenessReport.hasProjectDocs) {
|
|
243
262
|
console.log(`- Project docs detected: ${projectDocStalenessReport.checkedFileNames.length}`);
|
|
244
263
|
console.log(`- Project docs expected template version: ${projectDocStalenessReport.expectedTemplateVersion}`);
|
|
245
264
|
console.log(`- Project docs stale files: ${projectDocStalenessReport.staleFiles.length}`);
|
|
246
265
|
}
|
|
247
266
|
|
|
267
|
+
if (managedSurfacePlan.staleFiles.length > 0 || managedSurfacePlan.staleDirectories.length > 0) {
|
|
268
|
+
console.log('\nManaged surface stale paths preview (up to 5):');
|
|
269
|
+
const previewPaths = [
|
|
270
|
+
...managedSurfacePlan.staleFiles,
|
|
271
|
+
...managedSurfacePlan.staleDirectories,
|
|
272
|
+
].slice(0, 5);
|
|
273
|
+
for (const previewPath of previewPaths) {
|
|
274
|
+
console.log(`- ${previewPath}`);
|
|
275
|
+
}
|
|
276
|
+
if (managedSurfacePlan.staleFiles.length + managedSurfacePlan.staleDirectories.length > previewPaths.length) {
|
|
277
|
+
console.log('- ...');
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
248
281
|
if (projectDocStalenessReport.staleFiles.length > 0) {
|
|
249
282
|
console.log('\n[WARN] Some project docs were generated from older template versions:');
|
|
250
283
|
for (const staleDoc of projectDocStalenessReport.staleFiles) {
|
|
@@ -261,7 +294,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
261
294
|
|
|
262
295
|
const shouldApplyUpgrade = upgradeOptions.skipConfirmation
|
|
263
296
|
? true
|
|
264
|
-
: await askYesNo('Apply upgrade and
|
|
297
|
+
: await askYesNo('Apply upgrade and synchronize managed files?', userInterface, true);
|
|
265
298
|
|
|
266
299
|
if (!shouldApplyUpgrade) {
|
|
267
300
|
console.log('Upgrade cancelled by user.');
|
|
@@ -271,6 +304,12 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
271
304
|
await createBackup(resolvedTargetDirectoryPath);
|
|
272
305
|
|
|
273
306
|
try {
|
|
307
|
+
const governanceSyncResult = await copyGovernanceAssetsToTarget(resolvedTargetDirectoryPath, {
|
|
308
|
+
includeMcpTemplate: upgradeOptions.includeMcpTemplate === true,
|
|
309
|
+
pruneManagedSurface: upgradeOptions.pruneManagedSurface === true,
|
|
310
|
+
managedSurfacePlan,
|
|
311
|
+
});
|
|
312
|
+
|
|
274
313
|
await fs.writeFile(currentRulesPath, plannedRulesContent, 'utf8');
|
|
275
314
|
await fs.writeFile(path.join(resolvedTargetDirectoryPath, '.windsurfrules'), plannedRulesContent, 'utf8');
|
|
276
315
|
await writeSelectedPolicy(resolvedTargetDirectoryPath, selectedProfileName);
|
|
@@ -294,6 +333,8 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
294
333
|
|
|
295
334
|
console.log('\nUpgrade complete.');
|
|
296
335
|
console.log(`- Rules rewritten: ${isRulesContentChanged ? 'yes' : 'no (metadata refreshed)'}`);
|
|
336
|
+
console.log(`- Managed stale files removed: ${governanceSyncResult.deletedManagedFiles.length}`);
|
|
337
|
+
console.log(`- Managed stale directories removed: ${governanceSyncResult.deletedManagedDirectories.length}`);
|
|
297
338
|
console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
|
|
298
339
|
console.log('- Updated files: .cursorrules, .windsurfrules, .agent-context/state/onboarding-report.json');
|
|
299
340
|
} catch (error) {
|
package/lib/cli/utils.mjs
CHANGED
|
@@ -29,7 +29,7 @@ export function printUsage() {
|
|
|
29
29
|
console.log('Usage:');
|
|
30
30
|
console.log(' agentic-senior-core launch');
|
|
31
31
|
console.log(' agentic-senior-core init [target-directory] [--preset <name>] [--profile <beginner|balanced|strict>] [--profile-pack <name>] [--stack <name>] [--blueprint <name>] [--project-description <text>] [--architect-token-budget <number>] [--architect-timeout-ms <number>] [--architect-research-mode <snapshot|realtime>] [--enable-realtime-research] [--architect-realtime-signal-file <path>] [--ci <true|false>] [--newbie] [--token-optimize] [--no-token-optimize] [--token-agent <name>] [--memory-continuity] [--no-memory-continuity] [--scaffold-docs] [--no-scaffold-docs] [--docs-lang <en|id>] [--project-config <path>] [--runtime-env <auto|linux-wsl|linux|windows|macos>]');
|
|
32
|
-
console.log(' agentic-senior-core upgrade [target-directory] [--dry-run] [--yes] [--mcp-template]');
|
|
32
|
+
console.log(' agentic-senior-core upgrade [target-directory] [--dry-run] [--yes] [--mcp-template] [--no-mcp-template] [--prune] [--no-prune]');
|
|
33
33
|
console.log(' agentic-senior-core optimize [target-directory] [--agent <copilot|claude|cursor|windsurf|gemini|codex|cline>] [--enable|--disable] [--show]');
|
|
34
34
|
console.log(' agentic-senior-core mcp');
|
|
35
35
|
console.log(' agentic-senior-core rollback [target-directory]');
|
|
@@ -66,6 +66,8 @@ export function printUsage() {
|
|
|
66
66
|
console.log(' --runtime-env Override runtime environment hint (auto, linux-wsl, linux, windows, macos)');
|
|
67
67
|
console.log(' --dry-run Preview upgrade without writing files');
|
|
68
68
|
console.log(' --yes Skip confirmation prompts for upgrade');
|
|
69
|
+
console.log(' --prune Keep managed governance files synchronized 1:1 (default in upgrade)');
|
|
70
|
+
console.log(' --no-prune Do not remove stale managed governance files during upgrade');
|
|
69
71
|
console.log(' --agent Target agent integration for token optimization mode');
|
|
70
72
|
console.log(' --enable Enable token optimization policy and rebuild compiled rules');
|
|
71
73
|
console.log(' --disable Disable token optimization policy and rebuild compiled rules');
|
|
@@ -110,11 +112,188 @@ export async function copyDirectory(sourceDirectoryPath, targetDirectoryPath) {
|
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
|
|
115
|
+
function toPosixRelativePath(relativePath) {
|
|
116
|
+
return relativePath.split(path.sep).join('/');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function isPathWithinPrefix(relativePath, prefixPath) {
|
|
120
|
+
const normalizedRelativePath = toPosixRelativePath(relativePath).replace(/\/+$/g, '');
|
|
121
|
+
const normalizedPrefixPath = toPosixRelativePath(prefixPath).replace(/\/+$/g, '');
|
|
122
|
+
|
|
123
|
+
if (!normalizedPrefixPath) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return normalizedRelativePath === normalizedPrefixPath
|
|
128
|
+
|| normalizedRelativePath.startsWith(`${normalizedPrefixPath}/`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function collectRelativeTreeEntries(baseDirectoryPath, relativeRootPath) {
|
|
132
|
+
const files = [];
|
|
133
|
+
const directories = [];
|
|
134
|
+
|
|
135
|
+
if (!(await pathExists(baseDirectoryPath))) {
|
|
136
|
+
return { files, directories };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const normalizedRootPath = toPosixRelativePath(relativeRootPath);
|
|
140
|
+
directories.push(normalizedRootPath);
|
|
141
|
+
|
|
142
|
+
async function walkDirectory(currentDirectoryPath, currentRelativePath) {
|
|
143
|
+
const directoryEntries = await fs.readdir(currentDirectoryPath, { withFileTypes: true });
|
|
144
|
+
|
|
145
|
+
for (const directoryEntry of directoryEntries) {
|
|
146
|
+
const sourceEntryPath = path.join(currentDirectoryPath, directoryEntry.name);
|
|
147
|
+
const relativeEntryPath = toPosixRelativePath(path.join(currentRelativePath, directoryEntry.name));
|
|
148
|
+
|
|
149
|
+
if (directoryEntry.isDirectory()) {
|
|
150
|
+
directories.push(relativeEntryPath);
|
|
151
|
+
await walkDirectory(sourceEntryPath, relativeEntryPath);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
files.push(relativeEntryPath);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
await walkDirectory(baseDirectoryPath, normalizedRootPath);
|
|
160
|
+
return { files, directories };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async function buildManagedSourceManifest() {
|
|
164
|
+
const sourceFiles = new Set();
|
|
165
|
+
const sourceDirectories = new Set();
|
|
166
|
+
|
|
167
|
+
for (const sourceDirectoryName of directoryCopies) {
|
|
168
|
+
const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
|
|
169
|
+
const sourceTreeEntries = await collectRelativeTreeEntries(sourceDirectoryPath, sourceDirectoryName);
|
|
170
|
+
|
|
171
|
+
for (const sourceFilePath of sourceTreeEntries.files) {
|
|
172
|
+
sourceFiles.add(sourceFilePath);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
for (const sourceDirectoryPathRelative of sourceTreeEntries.directories) {
|
|
176
|
+
sourceDirectories.add(sourceDirectoryPathRelative);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
for (const entryPointFileName of entryPointFiles) {
|
|
181
|
+
const sourceFilePath = path.join(REPO_ROOT, entryPointFileName);
|
|
182
|
+
if (!(await pathExists(sourceFilePath))) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
sourceFiles.add(toPosixRelativePath(entryPointFileName));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
files: sourceFiles,
|
|
191
|
+
directories: sourceDirectories,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function collectManagedTargetManifest(resolvedTargetDirectoryPath) {
|
|
196
|
+
const targetFiles = new Set();
|
|
197
|
+
const targetDirectories = new Set();
|
|
198
|
+
|
|
199
|
+
for (const sourceDirectoryName of directoryCopies) {
|
|
200
|
+
const targetDirectoryPath = path.join(resolvedTargetDirectoryPath, sourceDirectoryName);
|
|
201
|
+
const targetTreeEntries = await collectRelativeTreeEntries(targetDirectoryPath, sourceDirectoryName);
|
|
202
|
+
|
|
203
|
+
for (const targetFilePath of targetTreeEntries.files) {
|
|
204
|
+
targetFiles.add(targetFilePath);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
for (const targetDirectoryPathRelative of targetTreeEntries.directories) {
|
|
208
|
+
targetDirectories.add(targetDirectoryPathRelative);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
for (const entryPointFileName of entryPointFiles) {
|
|
213
|
+
const targetFilePath = path.join(resolvedTargetDirectoryPath, entryPointFileName);
|
|
214
|
+
if (!(await pathExists(targetFilePath))) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
targetFiles.add(toPosixRelativePath(entryPointFileName));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
files: targetFiles,
|
|
223
|
+
directories: targetDirectories,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export async function analyzeManagedGovernanceSurface(
|
|
228
|
+
resolvedTargetDirectoryPath,
|
|
229
|
+
options = {}
|
|
230
|
+
) {
|
|
231
|
+
const preservePathPrefixes = Array.isArray(options.preservePathPrefixes)
|
|
232
|
+
? options.preservePathPrefixes
|
|
233
|
+
: ['.agent-context/state'];
|
|
234
|
+
|
|
235
|
+
const sourceManifest = await buildManagedSourceManifest();
|
|
236
|
+
const targetManifest = await collectManagedTargetManifest(resolvedTargetDirectoryPath);
|
|
237
|
+
|
|
238
|
+
const staleFiles = [];
|
|
239
|
+
const staleDirectories = [];
|
|
240
|
+
const preservedFiles = [];
|
|
241
|
+
const preservedDirectories = [];
|
|
242
|
+
|
|
243
|
+
const sortedTargetFiles = [...targetManifest.files].sort((leftPath, rightPath) => leftPath.localeCompare(rightPath));
|
|
244
|
+
const sortedTargetDirectories = [...targetManifest.directories].sort(
|
|
245
|
+
(leftPath, rightPath) => rightPath.length - leftPath.length || leftPath.localeCompare(rightPath)
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
for (const targetFilePath of sortedTargetFiles) {
|
|
249
|
+
if (sourceManifest.files.has(targetFilePath)) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (preservePathPrefixes.some((prefixPath) => isPathWithinPrefix(targetFilePath, prefixPath))) {
|
|
254
|
+
preservedFiles.push(targetFilePath);
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
staleFiles.push(targetFilePath);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
for (const targetDirectoryPathRelative of sortedTargetDirectories) {
|
|
262
|
+
if (sourceManifest.directories.has(targetDirectoryPathRelative)) {
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (preservePathPrefixes.some((prefixPath) => isPathWithinPrefix(targetDirectoryPathRelative, prefixPath))) {
|
|
267
|
+
preservedDirectories.push(targetDirectoryPathRelative);
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
staleDirectories.push(targetDirectoryPathRelative);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
staleFiles,
|
|
276
|
+
staleDirectories,
|
|
277
|
+
preservedFiles,
|
|
278
|
+
preservedDirectories,
|
|
279
|
+
managedSourceFileCount: sourceManifest.files.size,
|
|
280
|
+
managedSourceDirectoryCount: sourceManifest.directories.size,
|
|
281
|
+
managedTargetFileCount: targetManifest.files.size,
|
|
282
|
+
managedTargetDirectoryCount: targetManifest.directories.size,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
113
286
|
export async function copyGovernanceAssetsToTarget(
|
|
114
287
|
resolvedTargetDirectoryPath,
|
|
115
288
|
options = {}
|
|
116
289
|
) {
|
|
117
290
|
const shouldIncludeMcpTemplate = options.includeMcpTemplate === true;
|
|
291
|
+
const shouldPruneManagedSurface = options.pruneManagedSurface === true;
|
|
292
|
+
const managedSurfacePlan = shouldPruneManagedSurface
|
|
293
|
+
? options.managedSurfacePlan || await analyzeManagedGovernanceSurface(resolvedTargetDirectoryPath)
|
|
294
|
+
: null;
|
|
295
|
+
const deletedManagedFiles = [];
|
|
296
|
+
const deletedManagedDirectories = [];
|
|
118
297
|
|
|
119
298
|
for (const sourceDirectoryName of directoryCopies) {
|
|
120
299
|
const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
|
|
@@ -141,6 +320,28 @@ export async function copyGovernanceAssetsToTarget(
|
|
|
141
320
|
await fs.copyFile(sourceFilePath, targetFilePath);
|
|
142
321
|
}
|
|
143
322
|
|
|
323
|
+
if (shouldPruneManagedSurface && managedSurfacePlan) {
|
|
324
|
+
for (const staleFileRelativePath of managedSurfacePlan.staleFiles) {
|
|
325
|
+
const staleFilePath = path.join(resolvedTargetDirectoryPath, ...staleFileRelativePath.split('/'));
|
|
326
|
+
if (!(await pathExists(staleFilePath))) {
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
await fs.unlink(staleFilePath);
|
|
331
|
+
deletedManagedFiles.push(staleFileRelativePath);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
for (const staleDirectoryRelativePath of managedSurfacePlan.staleDirectories) {
|
|
335
|
+
const staleDirectoryPath = path.join(resolvedTargetDirectoryPath, ...staleDirectoryRelativePath.split('/'));
|
|
336
|
+
if (!(await pathExists(staleDirectoryPath))) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
await fs.rm(staleDirectoryPath, { recursive: true, force: true });
|
|
341
|
+
deletedManagedDirectories.push(staleDirectoryRelativePath);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
144
345
|
if (shouldIncludeMcpTemplate) {
|
|
145
346
|
const projectName = path.basename(resolvedTargetDirectoryPath);
|
|
146
347
|
const mcpArgs = ['./scripts/mcp-server.mjs'];
|
|
@@ -235,6 +436,12 @@ export async function copyGovernanceAssetsToTarget(
|
|
|
235
436
|
}
|
|
236
437
|
}
|
|
237
438
|
|
|
439
|
+
return {
|
|
440
|
+
deletedManagedFiles,
|
|
441
|
+
deletedManagedDirectories,
|
|
442
|
+
managedSurfacePlan,
|
|
443
|
+
};
|
|
444
|
+
|
|
238
445
|
}
|
|
239
446
|
|
|
240
447
|
export async function askChoice(promptMessage, options, userInterface) {
|