@nomadamas/k-skill 0.9.0 → 0.9.2
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/bin/k-skill.js +12 -0
- package/package.json +2 -2
- package/skills/k-skill-setup/instruction.md +10 -4
- package/skills/multi-asset-morning-briefing/instruction.md +117 -0
- package/skills/multi-asset-morning-briefing/references/format-rules.md +236 -0
- package/skills/multi-asset-morning-briefing/scripts/market_data.py +1003 -0
- package/skills/multi-asset-morning-briefing/skill.json +9 -0
- package/skills/store-longevity-radar/scripts/__pycache__/store_longevity_download.cpython-312.pyc +0 -0
- package/src/update.js +207 -0
- package/templates/core.md +1 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "multi-asset-morning-briefing",
|
|
3
|
+
"description": "글로벌 주식·금리·외환·원자재·변동성과 한국시장 전달 경로를 연결해 근거 링크가 있는 7개 섹션의 멀티에셋 모닝 브리핑을 작성한다. Use when the user asks 모닝 브리핑, Morning Call, 오버나이트 시황, 데일리 마켓 브리핑 또는 기존 브리핑 검수. Not for 실시간 호가, 국내 개별 종목 단독 조회(korean-stock-search), 투자 권유·매매 판단.",
|
|
4
|
+
"profiles": [
|
|
5
|
+
"lookup",
|
|
6
|
+
"browser"
|
|
7
|
+
],
|
|
8
|
+
"frontmatter": "name: multi-asset-morning-briefing\ndescription: 글로벌 주식·금리·외환·원자재·변동성과 한국시장 전달 경로를 연결해 근거 링크가 있는 7개 섹션의 멀티에셋 모닝 브리핑을 작성한다. Use when the user asks 모닝 브리핑, Morning Call, 오버나이트 시황, 데일리 마켓 브리핑 또는 기존 브리핑 검수. Not for 실시간 호가, 국내 개별 종목 단독 조회(korean-stock-search), 투자 권유·매매 판단.\nlicense: MIT\nmetadata:\n category: finance\n locale: ko-KR\n phase: v1"
|
|
9
|
+
}
|
package/skills/store-longevity-radar/scripts/__pycache__/store_longevity_download.cpython-312.pyc
CHANGED
|
Binary file
|
package/src/update.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const childProcess = require("node:child_process");
|
|
4
|
+
const { version: packageVersion } = require("../package.json");
|
|
5
|
+
|
|
6
|
+
const PACKAGE_NAME = "@nomadamas/k-skill";
|
|
7
|
+
const SKILLS_SOURCE = "NomaDamas/k-skill";
|
|
8
|
+
const UPDATE_INVOCATION = "npx -y @nomadamas/k-skill@0 update";
|
|
9
|
+
|
|
10
|
+
function defaultSpawn(command, args, options) {
|
|
11
|
+
return childProcess.spawnSync(command, args, {
|
|
12
|
+
encoding: "utf8",
|
|
13
|
+
...options,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isGlobalInstall(argv1 = process.argv[1]) {
|
|
18
|
+
const normalized = String(argv1 || "").replaceAll("\\", "/");
|
|
19
|
+
if (!normalized) return false;
|
|
20
|
+
if (normalized.includes("/_npx/") || normalized.includes("/.npm/_npx/")) return false;
|
|
21
|
+
return /\/node_modules\/@nomadamas\/k-skill\//.test(normalized);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function parseVersion(raw) {
|
|
25
|
+
const match = String(raw ?? "").trim().match(/(\d+)\.(\d+)\.(\d+)/);
|
|
26
|
+
if (!match) return null;
|
|
27
|
+
return {
|
|
28
|
+
major: Number(match[1]),
|
|
29
|
+
minor: Number(match[2]),
|
|
30
|
+
patch: Number(match[3]),
|
|
31
|
+
raw: `${match[1]}.${match[2]}.${match[3]}`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function compareVersions(left, right) {
|
|
36
|
+
if (left.major !== right.major) return left.major - right.major;
|
|
37
|
+
if (left.minor !== right.minor) return left.minor - right.minor;
|
|
38
|
+
return left.patch - right.patch;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function parseMaxVersion(raw) {
|
|
42
|
+
const text = String(raw ?? "");
|
|
43
|
+
const pattern = /(\d+)\.(\d+)\.(\d+)/g;
|
|
44
|
+
let best = null;
|
|
45
|
+
let match;
|
|
46
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
47
|
+
const candidate = {
|
|
48
|
+
major: Number(match[1]),
|
|
49
|
+
minor: Number(match[2]),
|
|
50
|
+
patch: Number(match[3]),
|
|
51
|
+
raw: `${match[1]}.${match[2]}.${match[3]}`,
|
|
52
|
+
};
|
|
53
|
+
if (!best || compareVersions(candidate, best) > 0) best = candidate;
|
|
54
|
+
}
|
|
55
|
+
return best;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function spawnOutput(result) {
|
|
59
|
+
return `${result?.stdout || ""}\n${result?.stderr || ""}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function isMissingAgentFailure(result) {
|
|
63
|
+
const text = spawnOutput(result);
|
|
64
|
+
return /no (coding )?agents?( detected| found)?/i.test(text) || /none detected/i.test(text);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function lookupLatest(spawn) {
|
|
68
|
+
const result = spawn("npm", ["view", `${PACKAGE_NAME}@0`, "version"], {
|
|
69
|
+
encoding: "utf8",
|
|
70
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
71
|
+
});
|
|
72
|
+
if (result.error || (result.status ?? 1) !== 0) {
|
|
73
|
+
const error = new Error((result.stderr || result.error?.message || "npm view failed").trim());
|
|
74
|
+
error.code = "EREGISTRY";
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
const parsed = parseMaxVersion(result.stdout);
|
|
78
|
+
if (!parsed) {
|
|
79
|
+
const error = new Error(`could not parse registry version from ${JSON.stringify(result.stdout)}`);
|
|
80
|
+
error.code = "EREGISTRY";
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
return parsed;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function refreshSkills(spawn) {
|
|
87
|
+
const result = spawn("npx", ["--yes", "skills", "add", SKILLS_SOURCE, "--all", "-g"], {
|
|
88
|
+
encoding: "utf8",
|
|
89
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
90
|
+
});
|
|
91
|
+
if (result.error) {
|
|
92
|
+
return { status: "failed", detail: result.error.message };
|
|
93
|
+
}
|
|
94
|
+
if ((result.status ?? 1) === 0) {
|
|
95
|
+
return { status: "refreshed" };
|
|
96
|
+
}
|
|
97
|
+
if (isMissingAgentFailure(result)) {
|
|
98
|
+
return { status: "skipped", detail: spawnOutput(result).trim() };
|
|
99
|
+
}
|
|
100
|
+
return { status: "failed", detail: spawnOutput(result).trim() };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function runUpdate(options = {}) {
|
|
104
|
+
const spawn = options.spawn || defaultSpawn;
|
|
105
|
+
const current = parseVersion(options.currentVersion || packageVersion);
|
|
106
|
+
const argv1 = options.argv1 || process.argv[1];
|
|
107
|
+
const checkOnly = Boolean(options.checkOnly);
|
|
108
|
+
|
|
109
|
+
if (!current) {
|
|
110
|
+
return {
|
|
111
|
+
ok: false,
|
|
112
|
+
cli: { status: "error", current: options.currentVersion || packageVersion, latest: null },
|
|
113
|
+
skills: { status: "skipped" },
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let latest;
|
|
118
|
+
try {
|
|
119
|
+
latest = lookupLatest(spawn);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
return {
|
|
122
|
+
ok: false,
|
|
123
|
+
cli: { status: "error", current: current.raw, latest: null, detail: error.message },
|
|
124
|
+
skills: { status: "skipped" },
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const cmp = compareVersions(current, latest);
|
|
129
|
+
if (checkOnly) {
|
|
130
|
+
return {
|
|
131
|
+
ok: true,
|
|
132
|
+
cli: {
|
|
133
|
+
status: cmp < 0 ? "outdated" : "already-latest",
|
|
134
|
+
current: current.raw,
|
|
135
|
+
latest: latest.raw,
|
|
136
|
+
},
|
|
137
|
+
skills: { status: "check" },
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let cliStatus = "already-latest";
|
|
142
|
+
if (cmp < 0 && isGlobalInstall(argv1)) {
|
|
143
|
+
const install = spawn("npm", ["install", "-g", `${PACKAGE_NAME}@0`], {
|
|
144
|
+
encoding: "utf8",
|
|
145
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
146
|
+
});
|
|
147
|
+
if (install.error || (install.status ?? 1) !== 0) {
|
|
148
|
+
return {
|
|
149
|
+
ok: false,
|
|
150
|
+
cli: {
|
|
151
|
+
status: "error",
|
|
152
|
+
current: current.raw,
|
|
153
|
+
latest: latest.raw,
|
|
154
|
+
detail: spawnOutput(install).trim() || install.error?.message,
|
|
155
|
+
},
|
|
156
|
+
skills: { status: "skipped" },
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
cliStatus = "updated";
|
|
160
|
+
} else if (cmp < 0) {
|
|
161
|
+
cliStatus = "stale";
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const skills = refreshSkills(spawn);
|
|
165
|
+
return {
|
|
166
|
+
ok: skills.status !== "failed",
|
|
167
|
+
cli: { status: cliStatus, current: current.raw, latest: latest.raw },
|
|
168
|
+
skills,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function formatUpdate(result) {
|
|
173
|
+
const current = result.cli.current || "unknown";
|
|
174
|
+
const latest = result.cli.latest || "unknown";
|
|
175
|
+
const lines = [];
|
|
176
|
+
|
|
177
|
+
switch (result.cli.status) {
|
|
178
|
+
case "error":
|
|
179
|
+
lines.push(`cli: error (${current} → ${latest})${result.cli.detail ? ` ${result.cli.detail}` : ""}`);
|
|
180
|
+
break;
|
|
181
|
+
case "stale":
|
|
182
|
+
lines.push(`cli: stale (${current} < ${latest}); re-run ${UPDATE_INVOCATION}`);
|
|
183
|
+
break;
|
|
184
|
+
case "outdated":
|
|
185
|
+
lines.push(`cli: outdated (${current} < ${latest})`);
|
|
186
|
+
break;
|
|
187
|
+
case "updated":
|
|
188
|
+
lines.push(`cli: updated (${current} → ${latest})`);
|
|
189
|
+
break;
|
|
190
|
+
default:
|
|
191
|
+
lines.push(`cli: already-latest (${current})`);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
lines.push(`skills: ${result.skills.status}`);
|
|
196
|
+
if (result.skills.detail) lines.push(result.skills.detail);
|
|
197
|
+
return `${lines.join("\n")}\n`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
module.exports = {
|
|
201
|
+
PACKAGE_NAME,
|
|
202
|
+
SKILLS_SOURCE,
|
|
203
|
+
UPDATE_INVOCATION,
|
|
204
|
+
formatUpdate,
|
|
205
|
+
isGlobalInstall,
|
|
206
|
+
runUpdate,
|
|
207
|
+
};
|
package/templates/core.md
CHANGED
|
@@ -3,3 +3,4 @@
|
|
|
3
3
|
- When the user asks for an action and the official surface supports it lawfully, continue beyond lookup through reversible preparation and execution. Do not declare completion at a result list, deep link, or handoff when the action can still be carried out.
|
|
4
4
|
- Immediately before an irreversible external side effect such as payment, message/email delivery, final submission, cancellation, account mutation, or public posting, call `clarify` with the exact target, amount/payload, and effect. Execute only after approval; do not ask again for already-approved reversible steps.
|
|
5
5
|
- Preserve hard boundaries for law, required physical presence, CAPTCHA, identity proofing, electronic signatures, and unsupported official surfaces. In those cases, complete the furthest lawful supported step and open or prepare the exact next official step for the user.
|
|
6
|
+
- Before using k-skill CLI tools, run `npx -y @nomadamas/k-skill@0 update` so the CLI and all coding-agent skill installs (including `~/.agents/skills`) are current.
|