claude-scope 0.8.10 → 0.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/claude-scope.cjs +338 -1
- package/package.json +1 -1
package/dist/claude-scope.cjs
CHANGED
|
@@ -7579,6 +7579,337 @@ init_cache_metrics();
|
|
|
7579
7579
|
init_config_count_widget();
|
|
7580
7580
|
init_context_widget();
|
|
7581
7581
|
init_cost_widget();
|
|
7582
|
+
|
|
7583
|
+
// src/widgets/dev-server/dev-server-widget.ts
|
|
7584
|
+
var import_node_child_process2 = require("node:child_process");
|
|
7585
|
+
var import_node_util3 = require("node:util");
|
|
7586
|
+
init_widget_types();
|
|
7587
|
+
init_theme();
|
|
7588
|
+
|
|
7589
|
+
// src/widgets/dev-server/styles.ts
|
|
7590
|
+
init_colors();
|
|
7591
|
+
var devServerStyles = {
|
|
7592
|
+
balanced: (data, colors2) => {
|
|
7593
|
+
if (!data.server) return "";
|
|
7594
|
+
const { name, icon, isRunning, isBuilding } = data.server;
|
|
7595
|
+
const status = isRunning ? "running" : isBuilding ? "building" : "stopped";
|
|
7596
|
+
const coloredName = colors2 ? colorize(name, colors2.name) : name;
|
|
7597
|
+
const coloredStatus = colors2 ? colorize(`(${status})`, colors2.status) : `(${status})`;
|
|
7598
|
+
return `${icon} ${coloredName} ${coloredStatus}`;
|
|
7599
|
+
},
|
|
7600
|
+
compact: (data, colors2) => {
|
|
7601
|
+
if (!data.server) return "";
|
|
7602
|
+
const { name, icon, isRunning, isBuilding } = data.server;
|
|
7603
|
+
const statusIcon = isRunning ? "\u{1F680}" : isBuilding ? "\u{1F528}" : "\u{1F4A4}";
|
|
7604
|
+
const coloredName = colors2 ? colorize(name, colors2.name) : name;
|
|
7605
|
+
return `${icon} ${coloredName} ${statusIcon}`;
|
|
7606
|
+
},
|
|
7607
|
+
playful: (data, colors2) => {
|
|
7608
|
+
if (!data.server) return "";
|
|
7609
|
+
const { name, isRunning, isBuilding } = data.server;
|
|
7610
|
+
const emoji = isRunning ? "\u{1F3C3}" : isBuilding ? "\u{1F528}" : "\u{1F4A4}";
|
|
7611
|
+
const coloredName = colors2 ? colorize(name, colors2.name) : name;
|
|
7612
|
+
return `${emoji} ${coloredName}`;
|
|
7613
|
+
},
|
|
7614
|
+
verbose: (data, colors2) => {
|
|
7615
|
+
if (!data.server) return "";
|
|
7616
|
+
const { name, isRunning, isBuilding } = data.server;
|
|
7617
|
+
const status = isRunning ? "running" : isBuilding ? "building" : "stopped";
|
|
7618
|
+
const label = colors2 ? colorize("Dev Server:", colors2.label) : "Dev Server:";
|
|
7619
|
+
const coloredName = colors2 ? colorize(name, colors2.name) : name;
|
|
7620
|
+
const coloredStatus = colors2 ? colorize(`(${status})`, colors2.status) : `(${status})`;
|
|
7621
|
+
return `${label} ${coloredName} ${coloredStatus}`;
|
|
7622
|
+
},
|
|
7623
|
+
labeled: (data, colors2) => {
|
|
7624
|
+
if (!data.server) return "";
|
|
7625
|
+
const { name, icon, isRunning } = data.server;
|
|
7626
|
+
const status = isRunning ? "\u{1F7E2}" : "\u{1F534}";
|
|
7627
|
+
const label = colors2 ? colorize("Server:", colors2.label) : "Server:";
|
|
7628
|
+
const coloredName = colors2 ? colorize(name, colors2.name) : name;
|
|
7629
|
+
return `${label} ${icon} ${coloredName} ${status}`;
|
|
7630
|
+
},
|
|
7631
|
+
indicator: (data, colors2) => {
|
|
7632
|
+
if (!data.server) return "";
|
|
7633
|
+
const { name, icon } = data.server;
|
|
7634
|
+
const coloredName = colors2 ? colorize(name, colors2.name) : name;
|
|
7635
|
+
return `\u25CF ${icon} ${coloredName}`;
|
|
7636
|
+
}
|
|
7637
|
+
};
|
|
7638
|
+
|
|
7639
|
+
// src/widgets/dev-server/dev-server-widget.ts
|
|
7640
|
+
var execFileAsync2 = (0, import_node_util3.promisify)(import_node_child_process2.execFile);
|
|
7641
|
+
var DevServerWidget = class {
|
|
7642
|
+
id = "dev-server";
|
|
7643
|
+
metadata = createWidgetMetadata(
|
|
7644
|
+
"Dev Server",
|
|
7645
|
+
"Detects running dev server processes",
|
|
7646
|
+
"1.0.0",
|
|
7647
|
+
"claude-scope",
|
|
7648
|
+
0
|
|
7649
|
+
);
|
|
7650
|
+
enabled = true;
|
|
7651
|
+
colors;
|
|
7652
|
+
_lineOverride;
|
|
7653
|
+
styleFn = devServerStyles.balanced;
|
|
7654
|
+
cwd = null;
|
|
7655
|
+
processPatterns = [
|
|
7656
|
+
// Generic server patterns (checked first to catch simple servers)
|
|
7657
|
+
{ regex: /(npm|npx)\s+exec\s+serve/i, name: "Server", icon: "\u{1F310}" },
|
|
7658
|
+
{ regex: /(python|python3)\s+-m\s+http\.server/i, name: "HTTP", icon: "\u{1F310}" },
|
|
7659
|
+
{ regex: /serve\s+\.?-l?\s*\d+/i, name: "Server", icon: "\u{1F310}" },
|
|
7660
|
+
// Generic dev/build patterns
|
|
7661
|
+
{ regex: /(npm|yarn|pnpm|bun)\s+run\s+dev/i, name: "Dev", icon: "\u{1F680}" },
|
|
7662
|
+
{ regex: /(npm|yarn|pnpm|bun)\s+run\s+build/i, name: "Build", icon: "\u{1F528}" },
|
|
7663
|
+
// Framework-specific patterns
|
|
7664
|
+
{ regex: /nuxt\s+dev/i, name: "Nuxt", icon: "\u26A1" },
|
|
7665
|
+
{ regex: /next\s+dev/i, name: "Next.js", icon: "\u25B2" },
|
|
7666
|
+
{ regex: /vite($|\s)/i, name: "Vite", icon: "\u26A1" },
|
|
7667
|
+
{ regex: /svelte-kit\s+dev|svelte\s+dev/i, name: "Svelte", icon: "\u{1F525}" },
|
|
7668
|
+
{ regex: /astro\s+dev/i, name: "Astro", icon: "\u{1F680}" },
|
|
7669
|
+
{ regex: /remix\s+dev|remix\s+watch/i, name: "Remix", icon: "\u{1F4BF}" }
|
|
7670
|
+
];
|
|
7671
|
+
constructor(colors2) {
|
|
7672
|
+
this.colors = colors2 ?? DEFAULT_THEME;
|
|
7673
|
+
}
|
|
7674
|
+
/**
|
|
7675
|
+
* Set display style
|
|
7676
|
+
* @param style - Style to use for rendering
|
|
7677
|
+
*/
|
|
7678
|
+
setStyle(style = "balanced") {
|
|
7679
|
+
const fn = devServerStyles[style];
|
|
7680
|
+
if (fn) {
|
|
7681
|
+
this.styleFn = fn;
|
|
7682
|
+
}
|
|
7683
|
+
}
|
|
7684
|
+
/**
|
|
7685
|
+
* Set display line override
|
|
7686
|
+
* @param line - Line number (0-indexed)
|
|
7687
|
+
*/
|
|
7688
|
+
setLine(line) {
|
|
7689
|
+
this._lineOverride = line;
|
|
7690
|
+
}
|
|
7691
|
+
/**
|
|
7692
|
+
* Get display line
|
|
7693
|
+
* @returns Line number (0-indexed)
|
|
7694
|
+
*/
|
|
7695
|
+
getLine() {
|
|
7696
|
+
return this._lineOverride ?? this.metadata.line ?? 0;
|
|
7697
|
+
}
|
|
7698
|
+
/**
|
|
7699
|
+
* Initialize widget with context
|
|
7700
|
+
* @param context - Widget initialization context
|
|
7701
|
+
*/
|
|
7702
|
+
async initialize(context) {
|
|
7703
|
+
this.enabled = context.config?.enabled !== false;
|
|
7704
|
+
}
|
|
7705
|
+
/**
|
|
7706
|
+
* Update widget with new stdin data
|
|
7707
|
+
* @param data - Stdin data from Claude Code
|
|
7708
|
+
*/
|
|
7709
|
+
async update(data) {
|
|
7710
|
+
this.cwd = data.cwd;
|
|
7711
|
+
}
|
|
7712
|
+
/**
|
|
7713
|
+
* Check if widget is enabled
|
|
7714
|
+
* @returns true if widget should render
|
|
7715
|
+
*/
|
|
7716
|
+
isEnabled() {
|
|
7717
|
+
return this.enabled;
|
|
7718
|
+
}
|
|
7719
|
+
/**
|
|
7720
|
+
* Cleanup resources
|
|
7721
|
+
*/
|
|
7722
|
+
async cleanup() {
|
|
7723
|
+
}
|
|
7724
|
+
/**
|
|
7725
|
+
* Render widget output
|
|
7726
|
+
* @param context - Render context
|
|
7727
|
+
* @returns Rendered string, or null if no dev server detected
|
|
7728
|
+
*/
|
|
7729
|
+
async render(_context) {
|
|
7730
|
+
if (!this.enabled || !this.cwd) {
|
|
7731
|
+
return null;
|
|
7732
|
+
}
|
|
7733
|
+
const server = await this.detectDevServer();
|
|
7734
|
+
if (!server) {
|
|
7735
|
+
return null;
|
|
7736
|
+
}
|
|
7737
|
+
const renderData = { server };
|
|
7738
|
+
return this.styleFn(renderData, this.colors.devServer);
|
|
7739
|
+
}
|
|
7740
|
+
/**
|
|
7741
|
+
* Detect running dev server by parsing system process list
|
|
7742
|
+
* @returns Detected server status or null
|
|
7743
|
+
*/
|
|
7744
|
+
async detectDevServer() {
|
|
7745
|
+
try {
|
|
7746
|
+
const { stdout } = await execFileAsync2("ps", ["aux"], {
|
|
7747
|
+
timeout: 1e3
|
|
7748
|
+
});
|
|
7749
|
+
for (const pattern of this.processPatterns) {
|
|
7750
|
+
if (pattern.regex.test(stdout)) {
|
|
7751
|
+
const isBuilding = pattern.name.toLowerCase().includes("build");
|
|
7752
|
+
const isRunning = !isBuilding;
|
|
7753
|
+
return {
|
|
7754
|
+
name: pattern.name,
|
|
7755
|
+
icon: pattern.icon,
|
|
7756
|
+
isRunning,
|
|
7757
|
+
isBuilding
|
|
7758
|
+
};
|
|
7759
|
+
}
|
|
7760
|
+
}
|
|
7761
|
+
} catch {
|
|
7762
|
+
}
|
|
7763
|
+
return null;
|
|
7764
|
+
}
|
|
7765
|
+
};
|
|
7766
|
+
|
|
7767
|
+
// src/widgets/docker/docker-widget.ts
|
|
7768
|
+
var import_node_child_process3 = require("node:child_process");
|
|
7769
|
+
var import_node_util4 = require("node:util");
|
|
7770
|
+
init_widget_types();
|
|
7771
|
+
init_theme();
|
|
7772
|
+
|
|
7773
|
+
// src/widgets/docker/styles.ts
|
|
7774
|
+
init_colors();
|
|
7775
|
+
var dockerStyles = {
|
|
7776
|
+
balanced: (data, colors2) => {
|
|
7777
|
+
const { running, total } = data.status;
|
|
7778
|
+
if (running === 0) return "";
|
|
7779
|
+
const status = running > 0 ? "\u{1F7E2}" : "\u26AA";
|
|
7780
|
+
const count = total > running ? `${running}/${total}` : `${running}`;
|
|
7781
|
+
const label = colors2 ? colorize("Docker:", colors2.label) : "Docker:";
|
|
7782
|
+
const coloredCount = colors2 ? colorize(count, colors2.count) : count;
|
|
7783
|
+
return `${label} ${coloredCount} ${status}`;
|
|
7784
|
+
},
|
|
7785
|
+
compact: (data, colors2) => {
|
|
7786
|
+
const { running, total } = data.status;
|
|
7787
|
+
if (running === 0) return "";
|
|
7788
|
+
const count = total > running ? `${running}/${total}` : `${running}`;
|
|
7789
|
+
const coloredCount = colors2 ? colorize(count, colors2.count) : count;
|
|
7790
|
+
return `\u{1F433} ${coloredCount}`;
|
|
7791
|
+
},
|
|
7792
|
+
playful: (data, colors2) => {
|
|
7793
|
+
const { running, total } = data.status;
|
|
7794
|
+
if (running === 0) return "\u{1F433} Docker: \u{1F4A4}";
|
|
7795
|
+
const status = running > 0 ? "\u{1F7E2}" : "\u26AA";
|
|
7796
|
+
const count = total > running ? `${running}/${total}` : `${running}`;
|
|
7797
|
+
const label = colors2 ? colorize("Docker:", colors2.label) : "Docker:";
|
|
7798
|
+
const coloredCount = colors2 ? colorize(count, colors2.count) : count;
|
|
7799
|
+
return `\u{1F433} ${label} ${coloredCount} ${status}`;
|
|
7800
|
+
},
|
|
7801
|
+
verbose: (data, colors2) => {
|
|
7802
|
+
const { running, total } = data.status;
|
|
7803
|
+
if (running === 0) {
|
|
7804
|
+
const label2 = colors2 ? colorize("Docker:", colors2.label) : "Docker:";
|
|
7805
|
+
return `${label2} no containers running`;
|
|
7806
|
+
}
|
|
7807
|
+
const label = colors2 ? colorize("Docker:", colors2.label) : "Docker:";
|
|
7808
|
+
const coloredRunning = colors2 ? colorize(String(running), colors2.count) : String(running);
|
|
7809
|
+
return `${label} ${coloredRunning} running${total > running ? ` / ${total} total` : ""}`;
|
|
7810
|
+
},
|
|
7811
|
+
labeled: (data, colors2) => {
|
|
7812
|
+
const { running, total } = data.status;
|
|
7813
|
+
if (running === 0) {
|
|
7814
|
+
const label2 = colors2 ? colorize("Docker:", colors2.label) : "Docker:";
|
|
7815
|
+
return `${label2} --`;
|
|
7816
|
+
}
|
|
7817
|
+
const count = total > running ? `${running}/${total}` : `${running}`;
|
|
7818
|
+
const label = colors2 ? colorize("Docker:", colors2.label) : "Docker:";
|
|
7819
|
+
const coloredCount = colors2 ? colorize(count, colors2.count) : count;
|
|
7820
|
+
return `${label} ${coloredCount}`;
|
|
7821
|
+
},
|
|
7822
|
+
indicator: (data, colors2) => {
|
|
7823
|
+
const { running, total } = data.status;
|
|
7824
|
+
if (running === 0) {
|
|
7825
|
+
const label2 = colors2 ? colorize("Docker:", colors2.label) : "Docker:";
|
|
7826
|
+
return `\u25CF ${label2} --`;
|
|
7827
|
+
}
|
|
7828
|
+
const count = total > running ? `${running}/${total}` : `${running}`;
|
|
7829
|
+
const label = colors2 ? colorize("Docker:", colors2.label) : "Docker:";
|
|
7830
|
+
const coloredCount = colors2 ? colorize(count, colors2.count) : count;
|
|
7831
|
+
return `\u25CF ${label} ${coloredCount}`;
|
|
7832
|
+
}
|
|
7833
|
+
};
|
|
7834
|
+
|
|
7835
|
+
// src/widgets/docker/docker-widget.ts
|
|
7836
|
+
var execFileAsync3 = (0, import_node_util4.promisify)(import_node_child_process3.execFile);
|
|
7837
|
+
var DockerWidget = class {
|
|
7838
|
+
id = "docker";
|
|
7839
|
+
metadata = createWidgetMetadata(
|
|
7840
|
+
"Docker",
|
|
7841
|
+
"Shows Docker container count and status",
|
|
7842
|
+
"1.0.0",
|
|
7843
|
+
"claude-scope",
|
|
7844
|
+
0
|
|
7845
|
+
);
|
|
7846
|
+
enabled = true;
|
|
7847
|
+
colors;
|
|
7848
|
+
_lineOverride;
|
|
7849
|
+
styleFn = dockerStyles.balanced;
|
|
7850
|
+
cachedStatus = null;
|
|
7851
|
+
lastCheck = 0;
|
|
7852
|
+
CACHE_TTL = 5e3;
|
|
7853
|
+
constructor(colors2) {
|
|
7854
|
+
this.colors = colors2 ?? DEFAULT_THEME;
|
|
7855
|
+
}
|
|
7856
|
+
setStyle(style = "balanced") {
|
|
7857
|
+
const fn = dockerStyles[style];
|
|
7858
|
+
if (fn) {
|
|
7859
|
+
this.styleFn = fn;
|
|
7860
|
+
}
|
|
7861
|
+
}
|
|
7862
|
+
setLine(line) {
|
|
7863
|
+
this._lineOverride = line;
|
|
7864
|
+
}
|
|
7865
|
+
getLine() {
|
|
7866
|
+
return this._lineOverride ?? this.metadata.line ?? 0;
|
|
7867
|
+
}
|
|
7868
|
+
async initialize(context) {
|
|
7869
|
+
this.enabled = context.config?.enabled !== false;
|
|
7870
|
+
}
|
|
7871
|
+
async update(_data) {
|
|
7872
|
+
}
|
|
7873
|
+
isEnabled() {
|
|
7874
|
+
return this.enabled;
|
|
7875
|
+
}
|
|
7876
|
+
async cleanup() {
|
|
7877
|
+
}
|
|
7878
|
+
async render(_context) {
|
|
7879
|
+
if (!this.enabled) {
|
|
7880
|
+
return null;
|
|
7881
|
+
}
|
|
7882
|
+
const now = Date.now();
|
|
7883
|
+
if (this.cachedStatus && now - this.lastCheck < this.CACHE_TTL) {
|
|
7884
|
+
return this.styleFn({ status: this.cachedStatus }, this.colors.docker);
|
|
7885
|
+
}
|
|
7886
|
+
const status = await this.getDockerStatus();
|
|
7887
|
+
this.cachedStatus = status;
|
|
7888
|
+
this.lastCheck = now;
|
|
7889
|
+
if (!status.isAvailable) {
|
|
7890
|
+
return null;
|
|
7891
|
+
}
|
|
7892
|
+
return this.styleFn({ status }, this.colors.docker);
|
|
7893
|
+
}
|
|
7894
|
+
async getDockerStatus() {
|
|
7895
|
+
try {
|
|
7896
|
+
await execFileAsync3("docker", ["info"], { timeout: 2e3 });
|
|
7897
|
+
const { stdout: runningOutput } = await execFileAsync3("docker", ["ps", "-q"], {
|
|
7898
|
+
timeout: 1e3
|
|
7899
|
+
});
|
|
7900
|
+
const running = runningOutput.trim().split("\n").filter((line) => line).length;
|
|
7901
|
+
const { stdout: allOutput } = await execFileAsync3("docker", ["ps", "-aq"], {
|
|
7902
|
+
timeout: 1e3
|
|
7903
|
+
});
|
|
7904
|
+
const total = allOutput.trim().split("\n").filter((line) => line).length;
|
|
7905
|
+
return { running, total, isAvailable: true };
|
|
7906
|
+
} catch {
|
|
7907
|
+
return { running: 0, total: 0, isAvailable: false };
|
|
7908
|
+
}
|
|
7909
|
+
}
|
|
7910
|
+
};
|
|
7911
|
+
|
|
7912
|
+
// src/core/widget-factory.ts
|
|
7582
7913
|
init_duration_widget();
|
|
7583
7914
|
init_git_tag_widget();
|
|
7584
7915
|
init_git_widget();
|
|
@@ -7616,6 +7947,10 @@ var WidgetFactory = class {
|
|
|
7616
7947
|
return new CacheMetricsWidget(DEFAULT_THEME);
|
|
7617
7948
|
case "active-tools":
|
|
7618
7949
|
return new ActiveToolsWidget(DEFAULT_THEME, this.transcriptProvider);
|
|
7950
|
+
case "dev-server":
|
|
7951
|
+
return new DevServerWidget(DEFAULT_THEME);
|
|
7952
|
+
case "docker":
|
|
7953
|
+
return new DockerWidget(DEFAULT_THEME);
|
|
7619
7954
|
default:
|
|
7620
7955
|
return null;
|
|
7621
7956
|
}
|
|
@@ -7634,7 +7969,9 @@ var WidgetFactory = class {
|
|
|
7634
7969
|
"git-tag",
|
|
7635
7970
|
"config-count",
|
|
7636
7971
|
"cache-metrics",
|
|
7637
|
-
"active-tools"
|
|
7972
|
+
"active-tools",
|
|
7973
|
+
"dev-server",
|
|
7974
|
+
"docker"
|
|
7638
7975
|
];
|
|
7639
7976
|
}
|
|
7640
7977
|
};
|