mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-21 02:24:09 -07:00
feat: add /features command and lifecycle visibility
This commit is contained in:
@@ -1126,6 +1126,13 @@ export class Config implements McpContext {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the feature gate for querying feature status.
|
||||
*/
|
||||
getFeatureGate(): FeatureGate {
|
||||
return this.featureGate;
|
||||
}
|
||||
|
||||
isInitialized(): boolean {
|
||||
return this.initialized;
|
||||
}
|
||||
|
||||
@@ -100,6 +100,48 @@ describe('FeatureGate', () => {
|
||||
expect(gate.enabled('testGA')).toBe(true);
|
||||
});
|
||||
|
||||
it('should return feature info with metadata', () => {
|
||||
const gate = DefaultFeatureGate.deepCopy();
|
||||
gate.add({
|
||||
feat1: [
|
||||
{
|
||||
preRelease: FeatureStage.Alpha,
|
||||
since: '0.1.0',
|
||||
description: 'Feature 1',
|
||||
},
|
||||
],
|
||||
feat2: [
|
||||
{
|
||||
preRelease: FeatureStage.Beta,
|
||||
since: '0.2.0',
|
||||
until: '0.3.0',
|
||||
description: 'Feature 2',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const info = gate.getFeatureInfo();
|
||||
const feat1 = info.find((f) => f.key === 'feat1');
|
||||
const feat2 = info.find((f) => f.key === 'feat2');
|
||||
|
||||
expect(feat1).toEqual({
|
||||
key: 'feat1',
|
||||
enabled: false,
|
||||
stage: FeatureStage.Alpha,
|
||||
since: '0.1.0',
|
||||
until: undefined,
|
||||
description: 'Feature 1',
|
||||
});
|
||||
expect(feat2).toEqual({
|
||||
key: 'feat2',
|
||||
enabled: true,
|
||||
stage: FeatureStage.Beta,
|
||||
since: '0.2.0',
|
||||
until: '0.3.0',
|
||||
description: 'Feature 2',
|
||||
});
|
||||
});
|
||||
|
||||
it('should respect allAlpha/allBeta toggles', () => {
|
||||
const gate = DefaultFeatureGate.deepCopy();
|
||||
gate.add({
|
||||
|
||||
@@ -67,6 +67,18 @@ export interface FeatureSpec {
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* FeatureInfo provides a summary of a feature's current state and metadata.
|
||||
*/
|
||||
export interface FeatureInfo {
|
||||
key: string;
|
||||
enabled: boolean;
|
||||
stage: FeatureStage;
|
||||
since?: string;
|
||||
until?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* FeatureGate provides a read-only interface to query feature status.
|
||||
*/
|
||||
@@ -79,6 +91,10 @@ export interface FeatureGate {
|
||||
* Returns all known feature keys.
|
||||
*/
|
||||
knownFeatures(): string[];
|
||||
/**
|
||||
* Returns all features with their status and metadata.
|
||||
*/
|
||||
getFeatureInfo(): FeatureInfo[];
|
||||
/**
|
||||
* Returns a mutable copy of the current gate.
|
||||
*/
|
||||
@@ -189,6 +205,22 @@ class FeatureGateImpl implements MutableFeatureGate {
|
||||
return Array.from(this.specs.keys());
|
||||
}
|
||||
|
||||
getFeatureInfo(): FeatureInfo[] {
|
||||
return Array.from(this.specs.entries())
|
||||
.map(([key, specs]) => {
|
||||
const latestSpec = specs[specs.length - 1];
|
||||
return {
|
||||
key,
|
||||
enabled: this.enabled(key),
|
||||
stage: latestSpec.preRelease,
|
||||
since: latestSpec.since,
|
||||
until: latestSpec.until,
|
||||
description: latestSpec.description,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => a.key.localeCompare(b.key));
|
||||
}
|
||||
|
||||
deepCopy(): MutableFeatureGate {
|
||||
const copy = new FeatureGateImpl();
|
||||
copy.specs = new Map(
|
||||
|
||||
Reference in New Issue
Block a user