@mytechtoday/augment-extensions 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -22
- package/README.md +105 -6
- package/augment-extensions/domain-rules/software-architecture/README.md +143 -143
- package/augment-extensions/domain-rules/software-architecture/examples/banking-layered.md +961 -961
- package/augment-extensions/domain-rules/software-architecture/examples/ecommerce-microservices.md +990 -990
- package/augment-extensions/domain-rules/software-architecture/examples/iot-eventdriven.md +882 -882
- package/augment-extensions/domain-rules/software-architecture/examples/monolith-to-microservices-migration.md +703 -703
- package/augment-extensions/domain-rules/software-architecture/examples/serverless-imageprocessing.md +957 -957
- package/augment-extensions/domain-rules/software-architecture/examples/trading-eventdriven.md +747 -747
- package/augment-extensions/domain-rules/software-architecture/module.json +119 -119
- package/augment-extensions/domain-rules/software-architecture/rules/challenges-solutions.md +763 -763
- package/augment-extensions/domain-rules/software-architecture/rules/definitions-terminology.md +409 -409
- package/augment-extensions/domain-rules/software-architecture/rules/design-principles.md +684 -684
- package/augment-extensions/domain-rules/software-architecture/rules/evaluation-testing.md +1381 -1381
- package/augment-extensions/domain-rules/software-architecture/rules/event-driven-architecture.md +616 -616
- package/augment-extensions/domain-rules/software-architecture/rules/fundamentals.md +306 -306
- package/augment-extensions/domain-rules/software-architecture/rules/industry-architectures.md +554 -554
- package/augment-extensions/domain-rules/software-architecture/rules/layered-architecture.md +776 -776
- package/augment-extensions/domain-rules/software-architecture/rules/microservices-architecture.md +503 -503
- package/augment-extensions/domain-rules/software-architecture/rules/modeling-documentation.md +1199 -1199
- package/augment-extensions/domain-rules/software-architecture/rules/monolithic-architecture.md +351 -351
- package/augment-extensions/domain-rules/software-architecture/rules/principles.md +556 -556
- package/augment-extensions/domain-rules/software-architecture/rules/quality-attributes.md +797 -797
- package/augment-extensions/domain-rules/software-architecture/rules/scalability-performance.md +1345 -1345
- package/augment-extensions/domain-rules/software-architecture/rules/security-architecture.md +1039 -1039
- package/augment-extensions/domain-rules/software-architecture/rules/serverless-architecture.md +711 -711
- package/augment-extensions/domain-rules/software-architecture/rules/skills-development.md +568 -568
- package/augment-extensions/domain-rules/software-architecture/rules/tools-methodologies.md +961 -961
- package/augment-extensions/visual-design/CHANGELOG.md +132 -132
- package/augment-extensions/visual-design/README.md +255 -255
- package/augment-extensions/visual-design/__tests__/README.md +119 -119
- package/augment-extensions/visual-design/__tests__/style-selector.test.ts +172 -172
- package/augment-extensions/visual-design/__tests__/vendor-styles.test.ts +214 -214
- package/augment-extensions/visual-design/domains/other/ai-prompt-helper.ts +157 -157
- package/augment-extensions/visual-design/domains/other/dotnet-application.ts +156 -156
- package/augment-extensions/visual-design/domains/other/linux-platform.ts +156 -156
- package/augment-extensions/visual-design/domains/other/mobile-application.ts +157 -157
- package/augment-extensions/visual-design/domains/other/motion-picture.ts +156 -156
- package/augment-extensions/visual-design/domains/other/os-application.ts +156 -156
- package/augment-extensions/visual-design/domains/other/print-campaigns.ts +158 -158
- package/augment-extensions/visual-design/domains/other/web-app.ts +157 -157
- package/augment-extensions/visual-design/domains/other/website.ts +161 -161
- package/augment-extensions/visual-design/domains/other/windows-platform.ts +156 -156
- package/augment-extensions/visual-design/domains/web-page-styles/amazon-cloudscape.ts +506 -506
- package/augment-extensions/visual-design/domains/web-page-styles/google-modern.ts +615 -615
- package/augment-extensions/visual-design/domains/web-page-styles/microsoft-fluent.ts +531 -531
- package/augment-extensions/visual-design/examples/README.md +97 -97
- package/augment-extensions/visual-design/examples/ai-prompt-generation.md +233 -233
- package/augment-extensions/visual-design/examples/basic-usage.md +216 -216
- package/augment-extensions/visual-design/examples/domain-workflows.md +257 -257
- package/augment-extensions/visual-design/examples/vendor-comparison.md +247 -247
- package/augment-extensions/visual-design/module.json +78 -78
- package/augment-extensions/visual-design/style-selector.ts +177 -177
- package/augment-extensions/visual-design/types.ts +302 -302
- package/augment-extensions/visual-design/visual-design-core.ts +469 -469
- package/augment-extensions/workflows/adr-support/README.md +227 -227
- package/augment-extensions/workflows/adr-support/__tests__/adr-validator.test.ts +203 -203
- package/augment-extensions/workflows/adr-support/adr-validator.ts +162 -162
- package/augment-extensions/workflows/adr-support/examples/complete-lifecycle-example.md +449 -449
- package/augment-extensions/workflows/adr-support/examples/integration-example.md +580 -580
- package/augment-extensions/workflows/adr-support/examples/superseding-example.md +436 -436
- package/augment-extensions/workflows/adr-support/module.json +112 -112
- package/augment-extensions/workflows/adr-support/rules/adr-creation.md +372 -372
- package/augment-extensions/workflows/adr-support/rules/beads-integration.md +443 -443
- package/augment-extensions/workflows/adr-support/rules/conflict-detection.md +486 -486
- package/augment-extensions/workflows/adr-support/rules/decision-detection.md +362 -362
- package/augment-extensions/workflows/adr-support/rules/lifecycle-management.md +427 -427
- package/augment-extensions/workflows/adr-support/rules/openspec-integration.md +465 -465
- package/augment-extensions/workflows/adr-support/rules/template-selection.md +405 -405
- package/augment-extensions/workflows/adr-support/rules/validation-rules.md +543 -543
- package/augment-extensions/workflows/adr-support/schemas/adr-config.json +191 -191
- package/augment-extensions/workflows/adr-support/schemas/adr-metadata.json +172 -172
- package/augment-extensions/workflows/adr-support/templates/business-case.md +235 -235
- package/augment-extensions/workflows/adr-support/templates/madr-elaborate.md +197 -197
- package/augment-extensions/workflows/adr-support/templates/madr-simple.md +68 -68
- package/augment-extensions/workflows/adr-support/templates/nygard.md +84 -84
- package/augment-extensions/writing-standards/screenplay/rules/file-organization.md +213 -213
- package/augment-extensions/writing-standards/screenplay/utils/__tests__/file-organization.test.ts +169 -169
- package/augment-extensions/writing-standards/screenplay/utils/file-organization.ts +165 -165
- package/cli/dist/commands/agent.d.ts +37 -0
- package/cli/dist/commands/agent.d.ts.map +1 -0
- package/cli/dist/commands/agent.js +222 -0
- package/cli/dist/commands/agent.js.map +1 -0
- package/cli/dist/commands/beads.d.ts +64 -0
- package/cli/dist/commands/beads.d.ts.map +1 -0
- package/cli/dist/commands/beads.js +377 -0
- package/cli/dist/commands/beads.js.map +1 -0
- package/cli/dist/commands/change.d.ts +54 -0
- package/cli/dist/commands/change.d.ts.map +1 -0
- package/cli/dist/commands/change.js +243 -0
- package/cli/dist/commands/change.js.map +1 -0
- package/cli/dist/commands/clean.d.ts +15 -0
- package/cli/dist/commands/clean.d.ts.map +1 -0
- package/cli/dist/commands/clean.js +63 -0
- package/cli/dist/commands/clean.js.map +1 -0
- package/cli/dist/commands/clone.d.ts +15 -0
- package/cli/dist/commands/clone.d.ts.map +1 -0
- package/cli/dist/commands/clone.js +49 -0
- package/cli/dist/commands/clone.js.map +1 -0
- package/cli/dist/commands/config.d.ts +33 -0
- package/cli/dist/commands/config.d.ts.map +1 -0
- package/cli/dist/commands/config.js +166 -0
- package/cli/dist/commands/config.js.map +1 -0
- package/cli/dist/commands/context.d.ts +38 -0
- package/cli/dist/commands/context.d.ts.map +1 -0
- package/cli/dist/commands/context.js +205 -0
- package/cli/dist/commands/context.js.map +1 -0
- package/cli/dist/commands/create.d.ts +18 -0
- package/cli/dist/commands/create.d.ts.map +1 -0
- package/cli/dist/commands/create.js +178 -0
- package/cli/dist/commands/create.js.map +1 -0
- package/cli/dist/commands/diff.d.ts +19 -0
- package/cli/dist/commands/diff.d.ts.map +1 -0
- package/cli/dist/commands/diff.js +104 -0
- package/cli/dist/commands/diff.js.map +1 -0
- package/cli/dist/commands/doctor.d.ts +14 -0
- package/cli/dist/commands/doctor.d.ts.map +1 -0
- package/cli/dist/commands/doctor.js +62 -0
- package/cli/dist/commands/doctor.js.map +1 -0
- package/cli/dist/commands/export.d.ts +28 -0
- package/cli/dist/commands/export.d.ts.map +1 -0
- package/cli/dist/commands/export.js +135 -0
- package/cli/dist/commands/export.js.map +1 -0
- package/cli/dist/commands/import.d.ts +23 -0
- package/cli/dist/commands/import.d.ts.map +1 -0
- package/cli/dist/commands/import.js +118 -0
- package/cli/dist/commands/import.js.map +1 -0
- package/cli/dist/commands/prompt.d.ts +45 -0
- package/cli/dist/commands/prompt.d.ts.map +1 -0
- package/cli/dist/commands/prompt.js +223 -0
- package/cli/dist/commands/prompt.js.map +1 -0
- package/cli/dist/commands/spec.d.ts +57 -0
- package/cli/dist/commands/spec.d.ts.map +1 -0
- package/cli/dist/commands/spec.js +279 -0
- package/cli/dist/commands/spec.js.map +1 -0
- package/cli/dist/commands/stats.d.ts +18 -0
- package/cli/dist/commands/stats.d.ts.map +1 -0
- package/cli/dist/commands/stats.js +85 -0
- package/cli/dist/commands/stats.js.map +1 -0
- package/cli/dist/commands/task.d.ts +65 -0
- package/cli/dist/commands/task.d.ts.map +1 -0
- package/cli/dist/commands/task.js +282 -0
- package/cli/dist/commands/task.js.map +1 -0
- package/cli/dist/commands/template.d.ts +17 -0
- package/cli/dist/commands/template.d.ts.map +1 -0
- package/cli/dist/commands/template.js +55 -0
- package/cli/dist/commands/template.js.map +1 -0
- package/cli/dist/utils/agent-config.d.ts +129 -0
- package/cli/dist/utils/agent-config.d.ts.map +1 -0
- package/cli/dist/utils/agent-config.js +297 -0
- package/cli/dist/utils/agent-config.js.map +1 -0
- package/cli/dist/utils/auto-sync.js +19 -19
- package/cli/dist/utils/beads-graph.d.ts +17 -0
- package/cli/dist/utils/beads-graph.d.ts.map +1 -0
- package/cli/dist/utils/beads-graph.js +150 -0
- package/cli/dist/utils/beads-graph.js.map +1 -0
- package/cli/dist/utils/beads-integration.d.ts +112 -0
- package/cli/dist/utils/beads-integration.d.ts.map +1 -0
- package/cli/dist/utils/beads-integration.js +312 -0
- package/cli/dist/utils/beads-integration.js.map +1 -0
- package/cli/dist/utils/beads-reporter.d.ts +17 -0
- package/cli/dist/utils/beads-reporter.d.ts.map +1 -0
- package/cli/dist/utils/beads-reporter.js +160 -0
- package/cli/dist/utils/beads-reporter.js.map +1 -0
- package/cli/dist/utils/cache-manager.d.ts +55 -0
- package/cli/dist/utils/cache-manager.d.ts.map +1 -0
- package/cli/dist/utils/cache-manager.js +150 -0
- package/cli/dist/utils/cache-manager.js.map +1 -0
- package/cli/dist/utils/change-manager.d.ts +70 -0
- package/cli/dist/utils/change-manager.d.ts.map +1 -0
- package/cli/dist/utils/change-manager.js +412 -0
- package/cli/dist/utils/change-manager.js.map +1 -0
- package/cli/dist/utils/config-manager-enhanced.d.ts +66 -0
- package/cli/dist/utils/config-manager-enhanced.d.ts.map +1 -0
- package/cli/dist/utils/config-manager-enhanced.js +77 -0
- package/cli/dist/utils/config-manager-enhanced.js.map +1 -0
- package/cli/dist/utils/context-manager.d.ts +96 -0
- package/cli/dist/utils/context-manager.d.ts.map +1 -0
- package/cli/dist/utils/context-manager.js +258 -0
- package/cli/dist/utils/context-manager.js.map +1 -0
- package/cli/dist/utils/diff-engine.d.ts +78 -0
- package/cli/dist/utils/diff-engine.d.ts.map +1 -0
- package/cli/dist/utils/diff-engine.js +233 -0
- package/cli/dist/utils/diff-engine.js.map +1 -0
- package/cli/dist/utils/export-system.d.ts +101 -0
- package/cli/dist/utils/export-system.d.ts.map +1 -0
- package/cli/dist/utils/export-system.js +289 -0
- package/cli/dist/utils/export-system.js.map +1 -0
- package/cli/dist/utils/health-checker.d.ts +66 -0
- package/cli/dist/utils/health-checker.d.ts.map +1 -0
- package/cli/dist/utils/health-checker.js +285 -0
- package/cli/dist/utils/health-checker.js.map +1 -0
- package/cli/dist/utils/import-system.d.ts +74 -0
- package/cli/dist/utils/import-system.d.ts.map +1 -0
- package/cli/dist/utils/import-system.js +317 -0
- package/cli/dist/utils/import-system.js.map +1 -0
- package/cli/dist/utils/module-cloner.d.ts +40 -0
- package/cli/dist/utils/module-cloner.d.ts.map +1 -0
- package/cli/dist/utils/module-cloner.js +136 -0
- package/cli/dist/utils/module-cloner.js.map +1 -0
- package/cli/dist/utils/prompt-manager.d.ts +90 -0
- package/cli/dist/utils/prompt-manager.d.ts.map +1 -0
- package/cli/dist/utils/prompt-manager.js +302 -0
- package/cli/dist/utils/prompt-manager.js.map +1 -0
- package/cli/dist/utils/spec-manager.d.ts +65 -0
- package/cli/dist/utils/spec-manager.d.ts.map +1 -0
- package/cli/dist/utils/spec-manager.js +329 -0
- package/cli/dist/utils/spec-manager.js.map +1 -0
- package/cli/dist/utils/stats-collector.d.ts +74 -0
- package/cli/dist/utils/stats-collector.d.ts.map +1 -0
- package/cli/dist/utils/stats-collector.js +164 -0
- package/cli/dist/utils/stats-collector.js.map +1 -0
- package/cli/dist/utils/template-engine.d.ts +47 -0
- package/cli/dist/utils/template-engine.d.ts.map +1 -0
- package/cli/dist/utils/template-engine.js +204 -0
- package/cli/dist/utils/template-engine.js.map +1 -0
- package/package.json +12 -3
- package/augment-extensions/workflows/openspec/README.md +0 -96
- package/augment-extensions/workflows/openspec/examples/complete-change-example.md +0 -244
- package/augment-extensions/workflows/openspec/module.json +0 -54
- package/augment-extensions/workflows/openspec/rules/best-practices.md +0 -272
- package/augment-extensions/workflows/openspec/rules/manual-setup.md +0 -231
- package/augment-extensions/workflows/openspec/rules/spec-format.md +0 -236
- package/augment-extensions/workflows/openspec/rules/workflow.md +0 -214
- package/cli/dist/utils/__tests__/adr-validator.example.d.ts +0 -6
- package/cli/dist/utils/__tests__/adr-validator.example.d.ts.map +0 -1
- package/cli/dist/utils/__tests__/adr-validator.example.js +0 -148
- package/cli/dist/utils/__tests__/adr-validator.example.js.map +0 -1
- package/cli/dist/utils/adr-validator.d.ts +0 -65
- package/cli/dist/utils/adr-validator.d.ts.map +0 -1
- package/cli/dist/utils/adr-validator.js +0 -203
- package/cli/dist/utils/adr-validator.js.map +0 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache Manager for Augment Extensions
|
|
3
|
+
* Manages AI context cache
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Cache entry
|
|
7
|
+
*/
|
|
8
|
+
export interface CacheEntry {
|
|
9
|
+
key: string;
|
|
10
|
+
value: any;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
ttl?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Cache Manager class
|
|
16
|
+
*/
|
|
17
|
+
export declare class CacheManager {
|
|
18
|
+
private cacheDir;
|
|
19
|
+
private cacheFile;
|
|
20
|
+
private cache;
|
|
21
|
+
constructor(cacheDir?: string);
|
|
22
|
+
/**
|
|
23
|
+
* Get value from cache
|
|
24
|
+
*/
|
|
25
|
+
get(key: string): any | null;
|
|
26
|
+
/**
|
|
27
|
+
* Set value in cache
|
|
28
|
+
*/
|
|
29
|
+
set(key: string, value: any, ttl?: number): void;
|
|
30
|
+
/**
|
|
31
|
+
* Delete value from cache
|
|
32
|
+
*/
|
|
33
|
+
delete(key: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Clear all cache
|
|
36
|
+
*/
|
|
37
|
+
clear(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Get cache size
|
|
40
|
+
*/
|
|
41
|
+
size(): number;
|
|
42
|
+
/**
|
|
43
|
+
* Clean expired entries
|
|
44
|
+
*/
|
|
45
|
+
cleanExpired(): number;
|
|
46
|
+
/**
|
|
47
|
+
* Load cache from disk
|
|
48
|
+
*/
|
|
49
|
+
private loadCache;
|
|
50
|
+
/**
|
|
51
|
+
* Save cache to disk
|
|
52
|
+
*/
|
|
53
|
+
private saveCache;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=cache-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-manager.d.ts","sourceRoot":"","sources":["../../src/utils/cache-manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,GAAG,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAA0B;gBAE3B,QAAQ,GAAE,MAAyB;IAO/C;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI;IAgB5B;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAUhD;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAM5B;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,IAAI,IAAI,MAAM;IAId;;OAEG;IACH,YAAY,IAAI,MAAM;IAkBtB;;OAEG;IACH,OAAO,CAAC,SAAS;IAejB;;OAEG;IACH,OAAO,CAAC,SAAS;CASlB"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cache Manager for Augment Extensions
|
|
4
|
+
* Manages AI context cache
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.CacheManager = void 0;
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
/**
|
|
44
|
+
* Cache Manager class
|
|
45
|
+
*/
|
|
46
|
+
class CacheManager {
|
|
47
|
+
constructor(cacheDir = '.augment/cache') {
|
|
48
|
+
this.cacheDir = path.join(process.cwd(), cacheDir);
|
|
49
|
+
this.cacheFile = path.join(this.cacheDir, 'cache.json');
|
|
50
|
+
this.cache = new Map();
|
|
51
|
+
this.loadCache();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get value from cache
|
|
55
|
+
*/
|
|
56
|
+
get(key) {
|
|
57
|
+
const entry = this.cache.get(key);
|
|
58
|
+
if (!entry) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
// Check if expired
|
|
62
|
+
if (entry.ttl && Date.now() - entry.timestamp > entry.ttl * 1000) {
|
|
63
|
+
this.cache.delete(key);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return entry.value;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Set value in cache
|
|
70
|
+
*/
|
|
71
|
+
set(key, value, ttl) {
|
|
72
|
+
this.cache.set(key, {
|
|
73
|
+
key,
|
|
74
|
+
value,
|
|
75
|
+
timestamp: Date.now(),
|
|
76
|
+
ttl
|
|
77
|
+
});
|
|
78
|
+
this.saveCache();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Delete value from cache
|
|
82
|
+
*/
|
|
83
|
+
delete(key) {
|
|
84
|
+
const result = this.cache.delete(key);
|
|
85
|
+
this.saveCache();
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Clear all cache
|
|
90
|
+
*/
|
|
91
|
+
clear() {
|
|
92
|
+
this.cache.clear();
|
|
93
|
+
this.saveCache();
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get cache size
|
|
97
|
+
*/
|
|
98
|
+
size() {
|
|
99
|
+
return this.cache.size;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Clean expired entries
|
|
103
|
+
*/
|
|
104
|
+
cleanExpired() {
|
|
105
|
+
let cleaned = 0;
|
|
106
|
+
const now = Date.now();
|
|
107
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
108
|
+
if (entry.ttl && now - entry.timestamp > entry.ttl * 1000) {
|
|
109
|
+
this.cache.delete(key);
|
|
110
|
+
cleaned++;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (cleaned > 0) {
|
|
114
|
+
this.saveCache();
|
|
115
|
+
}
|
|
116
|
+
return cleaned;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Load cache from disk
|
|
120
|
+
*/
|
|
121
|
+
loadCache() {
|
|
122
|
+
try {
|
|
123
|
+
if (fs.existsSync(this.cacheFile)) {
|
|
124
|
+
const content = fs.readFileSync(this.cacheFile, 'utf-8');
|
|
125
|
+
const entries = JSON.parse(content);
|
|
126
|
+
for (const entry of entries) {
|
|
127
|
+
this.cache.set(entry.key, entry);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
// Ignore errors, start with empty cache
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Save cache to disk
|
|
137
|
+
*/
|
|
138
|
+
saveCache() {
|
|
139
|
+
try {
|
|
140
|
+
fs.mkdirSync(this.cacheDir, { recursive: true });
|
|
141
|
+
const entries = Array.from(this.cache.values());
|
|
142
|
+
fs.writeFileSync(this.cacheFile, JSON.stringify(entries, null, 2));
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
// Ignore errors
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
exports.CacheManager = CacheManager;
|
|
150
|
+
//# sourceMappingURL=cache-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-manager.js","sourceRoot":"","sources":["../../src/utils/cache-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenSpec Change Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages OpenSpec change proposals - creating, reading, validating, and archiving changes.
|
|
5
|
+
*/
|
|
6
|
+
export interface ChangeMetadata {
|
|
7
|
+
name: string;
|
|
8
|
+
title?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
status?: 'proposed' | 'in-progress' | 'completed' | 'archived';
|
|
11
|
+
created?: string;
|
|
12
|
+
updated?: string;
|
|
13
|
+
relatedSpec?: string;
|
|
14
|
+
jiraTicket?: string;
|
|
15
|
+
author?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface Change {
|
|
18
|
+
metadata: ChangeMetadata;
|
|
19
|
+
proposalContent: string;
|
|
20
|
+
tasksContent?: string;
|
|
21
|
+
changePath: string;
|
|
22
|
+
specs: string[];
|
|
23
|
+
jiraTickets: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* List all change proposals
|
|
27
|
+
*/
|
|
28
|
+
export declare function listChanges(options?: {
|
|
29
|
+
status?: string;
|
|
30
|
+
sort?: 'name' | 'created' | 'updated';
|
|
31
|
+
}): Change[];
|
|
32
|
+
/**
|
|
33
|
+
* Get a single change proposal by name
|
|
34
|
+
*/
|
|
35
|
+
export declare function getChange(changeName: string): Change | null;
|
|
36
|
+
/**
|
|
37
|
+
* Create a new change proposal
|
|
38
|
+
*/
|
|
39
|
+
export declare function createChange(changeName: string, options?: {
|
|
40
|
+
title?: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
template?: 'feature' | 'bugfix' | 'refactor';
|
|
43
|
+
relatedSpec?: string;
|
|
44
|
+
jiraTicket?: string;
|
|
45
|
+
}): string;
|
|
46
|
+
/**
|
|
47
|
+
* Validate a change proposal
|
|
48
|
+
*/
|
|
49
|
+
export declare function validateChange(changeName: string, options?: {
|
|
50
|
+
strict?: boolean;
|
|
51
|
+
}): {
|
|
52
|
+
valid: boolean;
|
|
53
|
+
errors: string[];
|
|
54
|
+
warnings: string[];
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Archive a change proposal
|
|
58
|
+
*/
|
|
59
|
+
export declare function archiveChange(changeName: string, options?: {
|
|
60
|
+
reason?: string;
|
|
61
|
+
closeTasks?: boolean;
|
|
62
|
+
}): string;
|
|
63
|
+
/**
|
|
64
|
+
* Get change statistics
|
|
65
|
+
*/
|
|
66
|
+
export declare function getChangeStats(): {
|
|
67
|
+
total: number;
|
|
68
|
+
byStatus: Record<string, number>;
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=change-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-manager.d.ts","sourceRoot":"","sources":["../../src/utils/change-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,UAAU,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,cAAc,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAMD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;CAClC,GAAG,MAAM,EAAE,CAuDhB;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqD3D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CAChB,GACL,MAAM,CAgER;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG;IACtF,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAwDA;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,MAAM,CA0CjH;AA0GD;;GAEG;AACH,wBAAgB,cAAc,IAAI;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAcA"}
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenSpec Change Manager
|
|
4
|
+
*
|
|
5
|
+
* Manages OpenSpec change proposals - creating, reading, validating, and archiving changes.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.listChanges = listChanges;
|
|
45
|
+
exports.getChange = getChange;
|
|
46
|
+
exports.createChange = createChange;
|
|
47
|
+
exports.validateChange = validateChange;
|
|
48
|
+
exports.archiveChange = archiveChange;
|
|
49
|
+
exports.getChangeStats = getChangeStats;
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const gray_matter_1 = __importDefault(require("gray-matter"));
|
|
53
|
+
const OPENSPEC_BASE = 'augment-extensions/openspec';
|
|
54
|
+
const CHANGES_DIR = path.join(OPENSPEC_BASE, 'changes');
|
|
55
|
+
const ARCHIVE_DIR = path.join(OPENSPEC_BASE, 'archive');
|
|
56
|
+
/**
|
|
57
|
+
* List all change proposals
|
|
58
|
+
*/
|
|
59
|
+
function listChanges(options = {}) {
|
|
60
|
+
const changes = [];
|
|
61
|
+
if (!fs.existsSync(CHANGES_DIR)) {
|
|
62
|
+
return changes;
|
|
63
|
+
}
|
|
64
|
+
const entries = fs.readdirSync(CHANGES_DIR, { withFileTypes: true });
|
|
65
|
+
for (const entry of entries) {
|
|
66
|
+
if (entry.isDirectory()) {
|
|
67
|
+
const changePath = path.join(CHANGES_DIR, entry.name);
|
|
68
|
+
const proposalPath = path.join(changePath, 'proposal.md');
|
|
69
|
+
if (fs.existsSync(proposalPath)) {
|
|
70
|
+
try {
|
|
71
|
+
const change = getChange(entry.name);
|
|
72
|
+
if (change) {
|
|
73
|
+
changes.push(change);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error(`Error reading change ${entry.name}:`, error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Apply filters
|
|
83
|
+
let filtered = changes;
|
|
84
|
+
if (options.status) {
|
|
85
|
+
filtered = filtered.filter(c => c.metadata.status === options.status);
|
|
86
|
+
}
|
|
87
|
+
// Sort
|
|
88
|
+
if (options.sort) {
|
|
89
|
+
filtered.sort((a, b) => {
|
|
90
|
+
switch (options.sort) {
|
|
91
|
+
case 'name':
|
|
92
|
+
return a.metadata.name.localeCompare(b.metadata.name);
|
|
93
|
+
case 'created':
|
|
94
|
+
const aCreated = a.metadata.created ? new Date(a.metadata.created).getTime() : 0;
|
|
95
|
+
const bCreated = b.metadata.created ? new Date(b.metadata.created).getTime() : 0;
|
|
96
|
+
return bCreated - aCreated;
|
|
97
|
+
case 'updated':
|
|
98
|
+
const aUpdated = a.metadata.updated ? new Date(a.metadata.updated).getTime() : 0;
|
|
99
|
+
const bUpdated = b.metadata.updated ? new Date(b.metadata.updated).getTime() : 0;
|
|
100
|
+
return bUpdated - aUpdated;
|
|
101
|
+
default:
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return filtered;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get a single change proposal by name
|
|
110
|
+
*/
|
|
111
|
+
function getChange(changeName) {
|
|
112
|
+
const changePath = path.join(CHANGES_DIR, changeName);
|
|
113
|
+
const proposalPath = path.join(changePath, 'proposal.md');
|
|
114
|
+
if (!fs.existsSync(proposalPath)) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
// Read proposal
|
|
119
|
+
const proposalContent = fs.readFileSync(proposalPath, 'utf-8');
|
|
120
|
+
const parsed = (0, gray_matter_1.default)(proposalContent);
|
|
121
|
+
const metadata = parsed.data;
|
|
122
|
+
if (!metadata.name) {
|
|
123
|
+
metadata.name = changeName;
|
|
124
|
+
}
|
|
125
|
+
// Read tasks if exists
|
|
126
|
+
let tasksContent;
|
|
127
|
+
const tasksPath = path.join(changePath, 'tasks.md');
|
|
128
|
+
if (fs.existsSync(tasksPath)) {
|
|
129
|
+
tasksContent = fs.readFileSync(tasksPath, 'utf-8');
|
|
130
|
+
}
|
|
131
|
+
// List specs
|
|
132
|
+
const specs = [];
|
|
133
|
+
const specsDir = path.join(changePath, 'specs');
|
|
134
|
+
if (fs.existsSync(specsDir)) {
|
|
135
|
+
const specFiles = fs.readdirSync(specsDir).filter(f => f.endsWith('.md'));
|
|
136
|
+
specs.push(...specFiles.map(f => path.join(specsDir, f)));
|
|
137
|
+
}
|
|
138
|
+
// List JIRA tickets
|
|
139
|
+
const jiraTickets = [];
|
|
140
|
+
const jiraDir = path.join(changePath, 'jira');
|
|
141
|
+
if (fs.existsSync(jiraDir)) {
|
|
142
|
+
const jiraFiles = fs.readdirSync(jiraDir);
|
|
143
|
+
jiraTickets.push(...jiraFiles);
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
metadata,
|
|
147
|
+
proposalContent: parsed.content,
|
|
148
|
+
tasksContent,
|
|
149
|
+
changePath,
|
|
150
|
+
specs,
|
|
151
|
+
jiraTickets
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error(`Error reading change ${changeName}:`, error);
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Create a new change proposal
|
|
161
|
+
*/
|
|
162
|
+
function createChange(changeName, options = {}) {
|
|
163
|
+
const changePath = path.join(CHANGES_DIR, changeName);
|
|
164
|
+
// Check if change already exists
|
|
165
|
+
if (fs.existsSync(changePath)) {
|
|
166
|
+
throw new Error(`Change already exists: ${changeName}`);
|
|
167
|
+
}
|
|
168
|
+
// Create directory structure
|
|
169
|
+
fs.mkdirSync(changePath, { recursive: true });
|
|
170
|
+
fs.mkdirSync(path.join(changePath, 'specs'), { recursive: true });
|
|
171
|
+
if (options.jiraTicket) {
|
|
172
|
+
fs.mkdirSync(path.join(changePath, 'jira'), { recursive: true });
|
|
173
|
+
}
|
|
174
|
+
// Create metadata
|
|
175
|
+
const metadata = {
|
|
176
|
+
name: changeName,
|
|
177
|
+
title: options.title || changeName,
|
|
178
|
+
status: 'proposed',
|
|
179
|
+
created: new Date().toISOString(),
|
|
180
|
+
updated: new Date().toISOString()
|
|
181
|
+
};
|
|
182
|
+
if (options.description) {
|
|
183
|
+
metadata.description = options.description;
|
|
184
|
+
}
|
|
185
|
+
if (options.relatedSpec) {
|
|
186
|
+
metadata.relatedSpec = options.relatedSpec;
|
|
187
|
+
}
|
|
188
|
+
if (options.jiraTicket) {
|
|
189
|
+
metadata.jiraTicket = options.jiraTicket;
|
|
190
|
+
}
|
|
191
|
+
// Get template content
|
|
192
|
+
const proposalTemplate = getProposalTemplate(options.template);
|
|
193
|
+
const tasksTemplate = getTasksTemplate();
|
|
194
|
+
// Replace placeholders
|
|
195
|
+
const proposalContent = proposalTemplate
|
|
196
|
+
.replace(/<title>/g, metadata.title || '')
|
|
197
|
+
.replace(/<description>/g, options.description || '')
|
|
198
|
+
.replace(/<date>/g, new Date().toISOString());
|
|
199
|
+
const tasksContent = tasksTemplate
|
|
200
|
+
.replace(/<changeName>/g, changeName)
|
|
201
|
+
.replace(/<title>/g, metadata.title || '');
|
|
202
|
+
// Create proposal.md
|
|
203
|
+
const proposalPath = path.join(changePath, 'proposal.md');
|
|
204
|
+
const proposalFile = gray_matter_1.default.stringify(proposalContent, metadata);
|
|
205
|
+
fs.writeFileSync(proposalPath, proposalFile, 'utf-8');
|
|
206
|
+
// Create tasks.md
|
|
207
|
+
const tasksPath = path.join(changePath, 'tasks.md');
|
|
208
|
+
fs.writeFileSync(tasksPath, tasksContent, 'utf-8');
|
|
209
|
+
// Create JIRA placeholder if specified
|
|
210
|
+
if (options.jiraTicket) {
|
|
211
|
+
const jiraPath = path.join(changePath, 'jira', `${options.jiraTicket}.md`);
|
|
212
|
+
fs.writeFileSync(jiraPath, `# JIRA Ticket: ${options.jiraTicket}\n\nRelated to change: ${changeName}\n`, 'utf-8');
|
|
213
|
+
}
|
|
214
|
+
return changePath;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Validate a change proposal
|
|
218
|
+
*/
|
|
219
|
+
function validateChange(changeName, options = {}) {
|
|
220
|
+
const errors = [];
|
|
221
|
+
const warnings = [];
|
|
222
|
+
const change = getChange(changeName);
|
|
223
|
+
if (!change) {
|
|
224
|
+
errors.push(`Change not found: ${changeName}`);
|
|
225
|
+
return { valid: false, errors, warnings };
|
|
226
|
+
}
|
|
227
|
+
// Check required files
|
|
228
|
+
const proposalPath = path.join(change.changePath, 'proposal.md');
|
|
229
|
+
const tasksPath = path.join(change.changePath, 'tasks.md');
|
|
230
|
+
if (!fs.existsSync(proposalPath)) {
|
|
231
|
+
errors.push('Missing required file: proposal.md');
|
|
232
|
+
}
|
|
233
|
+
if (!fs.existsSync(tasksPath)) {
|
|
234
|
+
warnings.push('Missing recommended file: tasks.md');
|
|
235
|
+
}
|
|
236
|
+
// Check required metadata
|
|
237
|
+
if (!change.metadata.name) {
|
|
238
|
+
errors.push('Missing required field: name');
|
|
239
|
+
}
|
|
240
|
+
if (!change.metadata.title) {
|
|
241
|
+
warnings.push('Missing recommended field: title');
|
|
242
|
+
}
|
|
243
|
+
if (!change.metadata.status) {
|
|
244
|
+
warnings.push('Missing recommended field: status');
|
|
245
|
+
}
|
|
246
|
+
// Check status value
|
|
247
|
+
if (change.metadata.status && !['proposed', 'in-progress', 'completed', 'archived'].includes(change.metadata.status)) {
|
|
248
|
+
errors.push(`Invalid status: ${change.metadata.status}`);
|
|
249
|
+
}
|
|
250
|
+
// Check proposal content
|
|
251
|
+
if (!change.proposalContent || change.proposalContent.trim().length === 0) {
|
|
252
|
+
warnings.push('Proposal content is empty');
|
|
253
|
+
}
|
|
254
|
+
// Check for JIRA integration
|
|
255
|
+
if (change.metadata.jiraTicket) {
|
|
256
|
+
const jiraDir = path.join(change.changePath, 'jira');
|
|
257
|
+
if (!fs.existsSync(jiraDir)) {
|
|
258
|
+
warnings.push('JIRA ticket specified but jira/ directory missing');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
valid: errors.length === 0,
|
|
263
|
+
errors,
|
|
264
|
+
warnings
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Archive a change proposal
|
|
269
|
+
*/
|
|
270
|
+
function archiveChange(changeName, options = {}) {
|
|
271
|
+
const change = getChange(changeName);
|
|
272
|
+
if (!change) {
|
|
273
|
+
throw new Error(`Change not found: ${changeName}`);
|
|
274
|
+
}
|
|
275
|
+
// Create archive directory
|
|
276
|
+
const archivePath = path.join(ARCHIVE_DIR, changeName);
|
|
277
|
+
if (fs.existsSync(archivePath)) {
|
|
278
|
+
throw new Error(`Archive already exists: ${changeName}`);
|
|
279
|
+
}
|
|
280
|
+
// Copy entire change directory to archive
|
|
281
|
+
copyDirectory(change.changePath, archivePath);
|
|
282
|
+
// Update metadata in archived proposal
|
|
283
|
+
const proposalPath = path.join(archivePath, 'proposal.md');
|
|
284
|
+
const content = fs.readFileSync(proposalPath, 'utf-8');
|
|
285
|
+
const parsed = (0, gray_matter_1.default)(content);
|
|
286
|
+
parsed.data.status = 'archived';
|
|
287
|
+
parsed.data.updated = new Date().toISOString();
|
|
288
|
+
const updatedContent = gray_matter_1.default.stringify(parsed.content, parsed.data);
|
|
289
|
+
fs.writeFileSync(proposalPath, updatedContent, 'utf-8');
|
|
290
|
+
// Create archive metadata
|
|
291
|
+
const archiveMetadata = {
|
|
292
|
+
archivedAt: new Date().toISOString(),
|
|
293
|
+
reason: options.reason || 'Archived',
|
|
294
|
+
originalPath: change.changePath
|
|
295
|
+
};
|
|
296
|
+
fs.writeFileSync(path.join(archivePath, 'archive-info.json'), JSON.stringify(archiveMetadata, null, 2), 'utf-8');
|
|
297
|
+
// Remove original directory
|
|
298
|
+
removeDirectory(change.changePath);
|
|
299
|
+
return archivePath;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Get proposal template
|
|
303
|
+
*/
|
|
304
|
+
function getProposalTemplate(templateType) {
|
|
305
|
+
const baseTemplate = `# <title>
|
|
306
|
+
|
|
307
|
+
## Overview
|
|
308
|
+
|
|
309
|
+
<description>
|
|
310
|
+
|
|
311
|
+
## Motivation
|
|
312
|
+
|
|
313
|
+
Why is this change needed?
|
|
314
|
+
|
|
315
|
+
## Proposed Changes
|
|
316
|
+
|
|
317
|
+
### Changes
|
|
318
|
+
|
|
319
|
+
- Change 1
|
|
320
|
+
- Change 2
|
|
321
|
+
|
|
322
|
+
### Impact
|
|
323
|
+
|
|
324
|
+
What will be affected by this change?
|
|
325
|
+
|
|
326
|
+
## Implementation Plan
|
|
327
|
+
|
|
328
|
+
1. Step 1
|
|
329
|
+
2. Step 2
|
|
330
|
+
|
|
331
|
+
## Testing
|
|
332
|
+
|
|
333
|
+
How will this be tested?
|
|
334
|
+
|
|
335
|
+
## Related
|
|
336
|
+
|
|
337
|
+
- Spec:
|
|
338
|
+
- Tasks: See tasks.md
|
|
339
|
+
`;
|
|
340
|
+
return baseTemplate;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Get tasks template
|
|
344
|
+
*/
|
|
345
|
+
function getTasksTemplate() {
|
|
346
|
+
return `# Tasks for <changeName>
|
|
347
|
+
|
|
348
|
+
## <title>
|
|
349
|
+
|
|
350
|
+
### Task List
|
|
351
|
+
|
|
352
|
+
- [ ] Task 1
|
|
353
|
+
- [ ] Task 2
|
|
354
|
+
- [ ] Task 3
|
|
355
|
+
|
|
356
|
+
### Dependencies
|
|
357
|
+
|
|
358
|
+
- Depends on:
|
|
359
|
+
- Blocks:
|
|
360
|
+
`;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Copy directory recursively
|
|
364
|
+
*/
|
|
365
|
+
function copyDirectory(src, dest) {
|
|
366
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
367
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
368
|
+
for (const entry of entries) {
|
|
369
|
+
const srcPath = path.join(src, entry.name);
|
|
370
|
+
const destPath = path.join(dest, entry.name);
|
|
371
|
+
if (entry.isDirectory()) {
|
|
372
|
+
copyDirectory(srcPath, destPath);
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
fs.copyFileSync(srcPath, destPath);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Remove directory recursively
|
|
381
|
+
*/
|
|
382
|
+
function removeDirectory(dir) {
|
|
383
|
+
if (fs.existsSync(dir)) {
|
|
384
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
385
|
+
for (const entry of entries) {
|
|
386
|
+
const fullPath = path.join(dir, entry.name);
|
|
387
|
+
if (entry.isDirectory()) {
|
|
388
|
+
removeDirectory(fullPath);
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
fs.unlinkSync(fullPath);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
fs.rmdirSync(dir);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Get change statistics
|
|
399
|
+
*/
|
|
400
|
+
function getChangeStats() {
|
|
401
|
+
const changes = listChanges();
|
|
402
|
+
const stats = {
|
|
403
|
+
total: changes.length,
|
|
404
|
+
byStatus: {}
|
|
405
|
+
};
|
|
406
|
+
for (const change of changes) {
|
|
407
|
+
const status = change.metadata.status || 'unknown';
|
|
408
|
+
stats.byStatus[status] = (stats.byStatus[status] || 0) + 1;
|
|
409
|
+
}
|
|
410
|
+
return stats;
|
|
411
|
+
}
|
|
412
|
+
//# sourceMappingURL=change-manager.js.map
|