@hasna/skills 0.10.47 → 0.10.49
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/README.md +34 -0
- package/bin/index.js +1091 -649
- package/bin/maintenance.js +18 -0
- package/bin/mcp.js +65 -2
- package/bin/migrate.js +19 -1
- package/bin/server.js +19 -1
- package/bin/worker.js +19 -1
- package/dist/cli/commands/runtime-launcher.d.ts +102 -0
- package/dist/cli/commands/runtime.d.ts +7 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/index.js +414 -262
- package/dist/lib/launch-cwd-apply.d.ts +1 -0
- package/dist/lib/launch-cwd.d.ts +5 -0
- package/dist/lib/self-spawn.d.ts +21 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/sdk/index.js +397 -245
- package/dist/server/index.d.ts +1 -1
- package/dist/server/maintenance.d.ts +1 -1
- package/dist/server/migrate.d.ts +17 -0
- package/dist/server/worker.d.ts +1 -0
- package/package.json +1 -1
package/bin/maintenance.js
CHANGED
|
@@ -1872,6 +1872,24 @@ var require_commander = __commonJS((exports) => {
|
|
|
1872
1872
|
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
1873
1873
|
});
|
|
1874
1874
|
|
|
1875
|
+
// src/lib/launch-cwd.ts
|
|
1876
|
+
var LAUNCH_CWD_VARIABLE = "HASNA_SKILLS_LAUNCH_CWD";
|
|
1877
|
+
function restoreLaunchCwd(env = process.env) {
|
|
1878
|
+
const requested = env[LAUNCH_CWD_VARIABLE];
|
|
1879
|
+
delete env[LAUNCH_CWD_VARIABLE];
|
|
1880
|
+
if (!requested || !requested.startsWith("/"))
|
|
1881
|
+
return { restored: false, cwd: process.cwd() };
|
|
1882
|
+
try {
|
|
1883
|
+
process.chdir(requested);
|
|
1884
|
+
return { restored: true, cwd: process.cwd() };
|
|
1885
|
+
} catch {
|
|
1886
|
+
return { restored: false, cwd: process.cwd() };
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
// src/lib/launch-cwd-apply.ts
|
|
1891
|
+
restoreLaunchCwd();
|
|
1892
|
+
|
|
1875
1893
|
// node_modules/commander/esm.mjs
|
|
1876
1894
|
var import__ = __toESM(require_commander(), 1);
|
|
1877
1895
|
var {
|
package/bin/mcp.js
CHANGED
|
@@ -20019,7 +20019,7 @@ var package_default;
|
|
|
20019
20019
|
var init_package = __esm(() => {
|
|
20020
20020
|
package_default = {
|
|
20021
20021
|
name: "@hasna/skills",
|
|
20022
|
-
version: "0.10.
|
|
20022
|
+
version: "0.10.49",
|
|
20023
20023
|
description: "Skills library for AI coding agents",
|
|
20024
20024
|
type: "module",
|
|
20025
20025
|
bin: {
|
|
@@ -48869,6 +48869,50 @@ function unchanged2(before) {
|
|
|
48869
48869
|
var sameStat = (a, b) => ["dev", "ino", "uid", "nlink", "mode", "size", "mtimeNs", "ctimeNs"].every((key) => a[key] === b[key]);
|
|
48870
48870
|
var init_codex_hook_trust_files = () => {};
|
|
48871
48871
|
|
|
48872
|
+
// src/cli/commands/runtime-launcher.ts
|
|
48873
|
+
var PINNED_LAUNCHER_BUN_FLAGS, PINNED_LAUNCHER_ENV_NAMES, PINNED_LAUNCHER_ENV_PREFIXES, ENV_PREFIX, ENV_EXACT, COMMAND_LINE, PINNED_LAUNCHER_MAX_BYTES;
|
|
48874
|
+
var init_runtime_launcher = __esm(() => {
|
|
48875
|
+
PINNED_LAUNCHER_BUN_FLAGS = ["--config=/dev/null", "--no-env-file", "--no-macros", "--no-install"];
|
|
48876
|
+
PINNED_LAUNCHER_ENV_NAMES = [
|
|
48877
|
+
"HOME",
|
|
48878
|
+
"PATH",
|
|
48879
|
+
"TMPDIR",
|
|
48880
|
+
"TERM",
|
|
48881
|
+
"TERM_PROGRAM",
|
|
48882
|
+
"TERM_PROGRAM_VERSION",
|
|
48883
|
+
"COLORTERM",
|
|
48884
|
+
"LANG",
|
|
48885
|
+
"USER",
|
|
48886
|
+
"LOGNAME",
|
|
48887
|
+
"SHELL",
|
|
48888
|
+
"TZ",
|
|
48889
|
+
"NO_COLOR",
|
|
48890
|
+
"FORCE_COLOR",
|
|
48891
|
+
"CI",
|
|
48892
|
+
"COLUMNS",
|
|
48893
|
+
"LINES",
|
|
48894
|
+
"EDITOR",
|
|
48895
|
+
"VISUAL",
|
|
48896
|
+
"PAGER",
|
|
48897
|
+
"SSH_AUTH_SOCK",
|
|
48898
|
+
"DATABASE_URL",
|
|
48899
|
+
"TERMINAL_CWD",
|
|
48900
|
+
"CODEX_HOME",
|
|
48901
|
+
"HERMES_HOME",
|
|
48902
|
+
"HERMES_ENABLE_PROJECT_PLUGINS",
|
|
48903
|
+
"HOST",
|
|
48904
|
+
"PORT",
|
|
48905
|
+
"NODE_ENV",
|
|
48906
|
+
"AGENT_ID",
|
|
48907
|
+
"ECS_CONTAINER_METADATA_URI_V4"
|
|
48908
|
+
];
|
|
48909
|
+
PINNED_LAUNCHER_ENV_PREFIXES = ["HASNA", "SKILLS", "SKILL", "MCP", "XDG", "LC", "AWS"];
|
|
48910
|
+
ENV_PREFIX = new RegExp(`^(${PINNED_LAUNCHER_ENV_PREFIXES.join("|")})_`);
|
|
48911
|
+
ENV_EXACT = new Set(PINNED_LAUNCHER_ENV_NAMES);
|
|
48912
|
+
COMMAND_LINE = new RegExp(`^set -- '([^']+)' ${PINNED_LAUNCHER_BUN_FLAGS.join(" ")} '--cwd=([^']+)' '([^']+)' "\\$@"$`, "m");
|
|
48913
|
+
PINNED_LAUNCHER_MAX_BYTES = 16 * 1024;
|
|
48914
|
+
});
|
|
48915
|
+
|
|
48872
48916
|
// src/lib/agent-integration.ts
|
|
48873
48917
|
var init_agent_integration = __esm(() => {
|
|
48874
48918
|
init_sumi_settings_witness();
|
|
@@ -48889,6 +48933,7 @@ var init_agent_integration = __esm(() => {
|
|
|
48889
48933
|
init_agent_hermes();
|
|
48890
48934
|
init_claude_settings_witness();
|
|
48891
48935
|
init_codex_hook_trust_files();
|
|
48936
|
+
init_runtime_launcher();
|
|
48892
48937
|
});
|
|
48893
48938
|
|
|
48894
48939
|
// src/lib/home-migration.ts
|
|
@@ -50902,7 +50947,7 @@ function resolveAgentDiscovery(options) {
|
|
|
50902
50947
|
throw new Error("Discovery review must include the agent configuration source");
|
|
50903
50948
|
const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical7(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical7(configPath), source)) : sources;
|
|
50904
50949
|
const reviewedSourcesWithManifestProjection = review.sources.map((source) => {
|
|
50905
|
-
if (agent !== "claude" || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes" || basename8(source.path) !== "plugin.json" || !source.path.endsWith(join26(sep6, ".claude-plugin", "plugin.json")))
|
|
50950
|
+
if (agent !== "claude" || source.sha256 === null || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes" || basename8(source.path) !== "plugin.json" || !source.path.endsWith(join26(sep6, ".claude-plugin", "plugin.json")))
|
|
50906
50951
|
return source;
|
|
50907
50952
|
const pluginRoot = dirname15(dirname15(source.path)), hooksPath = join26(pluginRoot, "hooks/hooks.json");
|
|
50908
50953
|
const hookStat = lstatSync18(hooksPath, { throwIfNoEntry: false });
|
|
@@ -63996,6 +64041,24 @@ var init_http = __esm(() => {
|
|
|
63996
64041
|
init_server3();
|
|
63997
64042
|
});
|
|
63998
64043
|
|
|
64044
|
+
// src/lib/launch-cwd.ts
|
|
64045
|
+
var LAUNCH_CWD_VARIABLE = "HASNA_SKILLS_LAUNCH_CWD";
|
|
64046
|
+
function restoreLaunchCwd(env = process.env) {
|
|
64047
|
+
const requested = env[LAUNCH_CWD_VARIABLE];
|
|
64048
|
+
delete env[LAUNCH_CWD_VARIABLE];
|
|
64049
|
+
if (!requested || !requested.startsWith("/"))
|
|
64050
|
+
return { restored: false, cwd: process.cwd() };
|
|
64051
|
+
try {
|
|
64052
|
+
process.chdir(requested);
|
|
64053
|
+
return { restored: true, cwd: process.cwd() };
|
|
64054
|
+
} catch {
|
|
64055
|
+
return { restored: false, cwd: process.cwd() };
|
|
64056
|
+
}
|
|
64057
|
+
}
|
|
64058
|
+
|
|
64059
|
+
// src/lib/launch-cwd-apply.ts
|
|
64060
|
+
restoreLaunchCwd();
|
|
64061
|
+
|
|
63999
64062
|
// src/mcp/index.ts
|
|
64000
64063
|
init_stdio2();
|
|
64001
64064
|
init_package();
|
package/bin/migrate.js
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
3
|
|
|
4
|
+
// src/lib/launch-cwd.ts
|
|
5
|
+
var LAUNCH_CWD_VARIABLE = "HASNA_SKILLS_LAUNCH_CWD";
|
|
6
|
+
function restoreLaunchCwd(env = process.env) {
|
|
7
|
+
const requested = env[LAUNCH_CWD_VARIABLE];
|
|
8
|
+
delete env[LAUNCH_CWD_VARIABLE];
|
|
9
|
+
if (!requested || !requested.startsWith("/"))
|
|
10
|
+
return { restored: false, cwd: process.cwd() };
|
|
11
|
+
try {
|
|
12
|
+
process.chdir(requested);
|
|
13
|
+
return { restored: true, cwd: process.cwd() };
|
|
14
|
+
} catch {
|
|
15
|
+
return { restored: false, cwd: process.cwd() };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// src/lib/launch-cwd-apply.ts
|
|
20
|
+
restoreLaunchCwd();
|
|
21
|
+
|
|
4
22
|
// src/server/migrate.ts
|
|
5
23
|
import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync3 } from "fs";
|
|
6
24
|
import { join as join5 } from "path";
|
|
7
25
|
// package.json
|
|
8
26
|
var package_default = {
|
|
9
27
|
name: "@hasna/skills",
|
|
10
|
-
version: "0.10.
|
|
28
|
+
version: "0.10.49",
|
|
11
29
|
description: "Skills library for AI coding agents",
|
|
12
30
|
type: "module",
|
|
13
31
|
bin: {
|
package/bin/server.js
CHANGED
|
@@ -24119,10 +24119,28 @@ __export(exports_dist_es8, {
|
|
|
24119
24119
|
var init_dist_es9 = __esm(() => {
|
|
24120
24120
|
init_fromIni();
|
|
24121
24121
|
});
|
|
24122
|
+
|
|
24123
|
+
// src/lib/launch-cwd.ts
|
|
24124
|
+
var LAUNCH_CWD_VARIABLE = "HASNA_SKILLS_LAUNCH_CWD";
|
|
24125
|
+
function restoreLaunchCwd(env = process.env) {
|
|
24126
|
+
const requested = env[LAUNCH_CWD_VARIABLE];
|
|
24127
|
+
delete env[LAUNCH_CWD_VARIABLE];
|
|
24128
|
+
if (!requested || !requested.startsWith("/"))
|
|
24129
|
+
return { restored: false, cwd: process.cwd() };
|
|
24130
|
+
try {
|
|
24131
|
+
process.chdir(requested);
|
|
24132
|
+
return { restored: true, cwd: process.cwd() };
|
|
24133
|
+
} catch {
|
|
24134
|
+
return { restored: false, cwd: process.cwd() };
|
|
24135
|
+
}
|
|
24136
|
+
}
|
|
24137
|
+
|
|
24138
|
+
// src/lib/launch-cwd-apply.ts
|
|
24139
|
+
restoreLaunchCwd();
|
|
24122
24140
|
// package.json
|
|
24123
24141
|
var package_default = {
|
|
24124
24142
|
name: "@hasna/skills",
|
|
24125
|
-
version: "0.10.
|
|
24143
|
+
version: "0.10.49",
|
|
24126
24144
|
description: "Skills library for AI coding agents",
|
|
24127
24145
|
type: "module",
|
|
24128
24146
|
bin: {
|
package/bin/worker.js
CHANGED
|
@@ -24120,12 +24120,30 @@ var init_dist_es9 = __esm(() => {
|
|
|
24120
24120
|
init_fromIni();
|
|
24121
24121
|
});
|
|
24122
24122
|
|
|
24123
|
+
// src/lib/launch-cwd.ts
|
|
24124
|
+
var LAUNCH_CWD_VARIABLE = "HASNA_SKILLS_LAUNCH_CWD";
|
|
24125
|
+
function restoreLaunchCwd(env = process.env) {
|
|
24126
|
+
const requested = env[LAUNCH_CWD_VARIABLE];
|
|
24127
|
+
delete env[LAUNCH_CWD_VARIABLE];
|
|
24128
|
+
if (!requested || !requested.startsWith("/"))
|
|
24129
|
+
return { restored: false, cwd: process.cwd() };
|
|
24130
|
+
try {
|
|
24131
|
+
process.chdir(requested);
|
|
24132
|
+
return { restored: true, cwd: process.cwd() };
|
|
24133
|
+
} catch {
|
|
24134
|
+
return { restored: false, cwd: process.cwd() };
|
|
24135
|
+
}
|
|
24136
|
+
}
|
|
24137
|
+
|
|
24138
|
+
// src/lib/launch-cwd-apply.ts
|
|
24139
|
+
restoreLaunchCwd();
|
|
24140
|
+
|
|
24123
24141
|
// src/server/worker.ts
|
|
24124
24142
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
24125
24143
|
// package.json
|
|
24126
24144
|
var package_default = {
|
|
24127
24145
|
name: "@hasna/skills",
|
|
24128
|
-
version: "0.10.
|
|
24146
|
+
version: "0.10.49",
|
|
24129
24147
|
description: "Skills library for AI coding agents",
|
|
24130
24148
|
type: "module",
|
|
24131
24149
|
bin: {
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export declare const PINNED_LAUNCHER_SCHEMA = "hasna-skills-pinned-launcher-v1";
|
|
2
|
+
/** The variable the launcher uses to hand the caller's directory to the CLI. */
|
|
3
|
+
export declare const LAUNCH_CWD_VARIABLE = "HASNA_SKILLS_LAUNCH_CWD";
|
|
4
|
+
/** Bun runtime flags that remove every working-directory configuration source. */
|
|
5
|
+
export declare const PINNED_LAUNCHER_BUN_FLAGS: readonly ["--config=/dev/null", "--no-env-file", "--no-macros", "--no-install"];
|
|
6
|
+
/**
|
|
7
|
+
* Environment names passed through `env -i`, by exact name. Everything else,
|
|
8
|
+
* including `BUN_*`, `NODE_OPTIONS`, `DYLD_*`, `LD_*` and proxy settings, is
|
|
9
|
+
* dropped. The handling is total on purpose: a name is either listed here,
|
|
10
|
+
* matches a prefix below, or never reaches the runtime.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PINNED_LAUNCHER_ENV_NAMES: readonly ["HOME", "PATH", "TMPDIR", "TERM", "TERM_PROGRAM", "TERM_PROGRAM_VERSION", "COLORTERM", "LANG", "USER", "LOGNAME", "SHELL", "TZ", "NO_COLOR", "FORCE_COLOR", "CI", "COLUMNS", "LINES", "EDITOR", "VISUAL", "PAGER", "SSH_AUTH_SOCK", "DATABASE_URL", "TERMINAL_CWD", "CODEX_HOME", "HERMES_HOME", "HERMES_ENABLE_PROJECT_PLUGINS", "HOST", "PORT", "NODE_ENV", "AGENT_ID", "ECS_CONTAINER_METADATA_URI_V4"];
|
|
13
|
+
/** Environment name prefixes passed through, for the app's own documented overrides. */
|
|
14
|
+
export declare const PINNED_LAUNCHER_ENV_PREFIXES: readonly ["HASNA", "SKILLS", "SKILL", "MCP", "XDG", "LC", "AWS"];
|
|
15
|
+
/** The allowlisted subset of an environment, by the same rule the launcher applies. */
|
|
16
|
+
export declare function pinnedLauncherEnvironment(env: Record<string, string | undefined>): Record<string, string>;
|
|
17
|
+
export type LauncherShape = "symlink" | "pinned";
|
|
18
|
+
export interface PinnedLauncherBinding {
|
|
19
|
+
runtime: string;
|
|
20
|
+
cwd: string;
|
|
21
|
+
entry: string;
|
|
22
|
+
}
|
|
23
|
+
export type LauncherState = {
|
|
24
|
+
shape: "symlink";
|
|
25
|
+
linkTarget: string;
|
|
26
|
+
target: string;
|
|
27
|
+
} | {
|
|
28
|
+
shape: "pinned";
|
|
29
|
+
runtime: string;
|
|
30
|
+
cwd: string;
|
|
31
|
+
target: string;
|
|
32
|
+
sha256: string;
|
|
33
|
+
};
|
|
34
|
+
export type InspectedLauncher = {
|
|
35
|
+
kind: "symlink";
|
|
36
|
+
linkTarget: string;
|
|
37
|
+
target: string;
|
|
38
|
+
} | {
|
|
39
|
+
kind: "pinned";
|
|
40
|
+
runtime: string;
|
|
41
|
+
cwd: string;
|
|
42
|
+
target: string;
|
|
43
|
+
sha256: string;
|
|
44
|
+
text: string;
|
|
45
|
+
} | {
|
|
46
|
+
kind: "foreign";
|
|
47
|
+
};
|
|
48
|
+
/** The exact launcher text for one Bun binary, trusted directory and entry. Deterministic. */
|
|
49
|
+
export declare function renderPinnedLauncher(binding: PinnedLauncherBinding): string;
|
|
50
|
+
/** Parse launcher text; only the exact rendered shape is accepted. */
|
|
51
|
+
export declare function parsePinnedLauncher(text: string): PinnedLauncherBinding | null;
|
|
52
|
+
/**
|
|
53
|
+
* Resolve a command path the way the symlink checks used to: the physical file
|
|
54
|
+
* it reaches and, when that file is a managed pinned launcher (its exact
|
|
55
|
+
* rendered text), the entry the launcher runs. `entry` equals `physical` for a
|
|
56
|
+
* symlink or a plain executable. A pinned entry must itself be a physical path.
|
|
57
|
+
*/
|
|
58
|
+
export declare function resolveLauncherCommand(path: string): {
|
|
59
|
+
physical: string;
|
|
60
|
+
entry: string;
|
|
61
|
+
pinned: (PinnedLauncherBinding & {
|
|
62
|
+
sha256: string;
|
|
63
|
+
}) | null;
|
|
64
|
+
};
|
|
65
|
+
/** Classify the launcher at `path` without following anything but its own symlink. */
|
|
66
|
+
export declare function inspectLauncher(path: string): InspectedLauncher;
|
|
67
|
+
/** The entry a managed launcher runs, whichever shape it has. */
|
|
68
|
+
export declare function launcherTarget(path: string): string;
|
|
69
|
+
/** The "link text" of a managed launcher: the symlink text, or the pinned entry path. */
|
|
70
|
+
export declare function launcherLinkText(path: string): string;
|
|
71
|
+
/** Whether the launcher at `path` is exactly `state`: same shape, text and target. */
|
|
72
|
+
export declare function launcherIs(path: string, state: LauncherState): boolean;
|
|
73
|
+
/** The pinned launcher text for a state, verified against the recorded digest. */
|
|
74
|
+
export declare function pinnedLauncherText(state: {
|
|
75
|
+
runtime: string;
|
|
76
|
+
cwd: string;
|
|
77
|
+
target: string;
|
|
78
|
+
sha256: string;
|
|
79
|
+
}): string;
|
|
80
|
+
/** Build the pinned state for an entry under the given Bun binary and trusted directory. */
|
|
81
|
+
export declare function pinnedLauncherState(runtime: string, cwd: string, target: string): Extract<LauncherState, {
|
|
82
|
+
shape: "pinned";
|
|
83
|
+
}>;
|
|
84
|
+
/**
|
|
85
|
+
* Create a launcher in `state` at a path that must not exist yet, and read it
|
|
86
|
+
* back. Symlinks are created as-is; pinned launchers are regular 0755 files.
|
|
87
|
+
*/
|
|
88
|
+
export declare function materializeLauncher(path: string, state: LauncherState): void;
|
|
89
|
+
/**
|
|
90
|
+
* The Bun binary launchers are pinned to: the exact runtime running the
|
|
91
|
+
* updater, resolved physically and required to be owned by root or the
|
|
92
|
+
* current user, executable, and not writable by group or others.
|
|
93
|
+
*/
|
|
94
|
+
export declare function pinnedLauncherRuntime(): string;
|
|
95
|
+
/** A pinned runtime is a physical, executable regular file owned by root or the current user and not group/world-writable. */
|
|
96
|
+
export declare function assertPinnedLauncherRuntimeSafe(runtime: string): void;
|
|
97
|
+
/**
|
|
98
|
+
* The launcher depends on `/bin/sh -p`, `/usr/bin/awk` and `/usr/bin/env`.
|
|
99
|
+
* Refuse before any launcher is written when this station's shell rejects
|
|
100
|
+
* `-p` (for example dash before 0.5.11), so no launcher is left unusable.
|
|
101
|
+
*/
|
|
102
|
+
export declare function assertPinnedLauncherShell(): void;
|
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
export declare function registerRuntime(parent: Command): void;
|
|
3
|
+
/**
|
|
4
|
+
* The command to run for the Skills selected on PATH, after checking that it
|
|
5
|
+
* runs the installed entry. A symlink is compared by its physical target, as
|
|
6
|
+
* before; a managed pinned launcher by the exact entry it runs, and it is run
|
|
7
|
+
* through the launcher so the caller's directory configures nothing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function selectedSkillsCommand(selected: string, installed: string): string;
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
|
|
2
|
+
import "../lib/launch-cwd-apply.js";
|