@skill-map/cli 0.42.0 → 0.43.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/dist/cli.js +316 -192
- package/dist/cli.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/kernel/index.d.ts +16 -24
- package/dist/kernel/index.js +4 -4
- package/dist/kernel/index.js.map +1 -1
- package/dist/migrations/001_initial.sql +6 -11
- package/dist/ui/chunk-2IF446BS.js +1 -0
- package/dist/ui/{chunk-5GD2GBPS.js → chunk-77J7XU3Y.js} +1 -1
- package/dist/ui/chunk-DIKPNZUZ.js +315 -0
- package/dist/ui/chunk-KGCJINI6.js +1 -0
- package/dist/ui/{chunk-XJL4DZ4M.js → chunk-PPE3P2JD.js} +1 -1
- package/dist/ui/{chunk-HWP3HM55.js → chunk-UOCACZLI.js} +1 -1
- package/dist/ui/{chunk-HEJCH7BA.js → chunk-YCR3XCIW.js} +5 -5
- package/dist/ui/index.html +1 -1
- package/dist/ui/main-VHFB7Q2D.js +3 -0
- package/migrations/001_initial.sql +6 -11
- package/package.json +3 -3
- package/dist/ui/chunk-HFPA56IM.js +0 -1
- package/dist/ui/chunk-HHPSCDLM.js +0 -315
- package/dist/ui/chunk-PZ6Q5AOT.js +0 -1
- package/dist/ui/main-7VYTTJP7.js +0 -3
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// cli/entry.ts
|
|
2
|
-
import { existsSync as
|
|
2
|
+
import { existsSync as existsSync32 } from "fs";
|
|
3
3
|
import { Builtins, Cli as Cli2 } from "clipanion";
|
|
4
4
|
|
|
5
5
|
// kernel/adapters/in-memory-progress.ts
|
|
@@ -244,11 +244,11 @@ function bucketByKind(kind, instance, bag) {
|
|
|
244
244
|
// plugins/claude/providers/claude/schemas/skill.schema.json
|
|
245
245
|
var skill_schema_default = {
|
|
246
246
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
247
|
-
$id: "https://skill-map.
|
|
247
|
+
$id: "https://skill-map.ai/providers/claude/v1/frontmatter/skill.schema.json",
|
|
248
248
|
title: "FrontmatterSkill",
|
|
249
249
|
description: "Frontmatter shape for nodes classified as `skill` by the Claude Provider. Today identical to `command` \u2014 both extend the shared `skill-base.schema.json` per Anthropic's documented merger (https://code.claude.com/docs/en/skills.md \u2014 \"Custom commands have been merged into skills\"). The two are kept SPLIT (not aliased) because skill-map's registry differentiates them in `IProviderKind.ui` (separate label / icon / color) and `defaultRefreshAction`. Splitting also reserves room for future divergence when one kind diverges from the other. No skill-only fields today; `additionalProperties: true` so the file is ready for them.",
|
|
250
250
|
allOf: [
|
|
251
|
-
{ $ref: "https://skill-map.
|
|
251
|
+
{ $ref: "https://skill-map.ai/providers/claude/v1/frontmatter/skill-base.schema.json" }
|
|
252
252
|
],
|
|
253
253
|
type: "object",
|
|
254
254
|
additionalProperties: true,
|
|
@@ -258,11 +258,11 @@ var skill_schema_default = {
|
|
|
258
258
|
// plugins/claude/providers/claude/schemas/skill-base.schema.json
|
|
259
259
|
var skill_base_schema_default = {
|
|
260
260
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
261
|
-
$id: "https://skill-map.
|
|
261
|
+
$id: "https://skill-map.ai/providers/claude/v1/frontmatter/skill-base.schema.json",
|
|
262
262
|
title: "FrontmatterSkillBase",
|
|
263
263
|
description: 'Shared frontmatter base for `skill` and `command` nodes per Anthropic\'s documented merger (https://code.claude.com/docs/en/skills.md \u2014 "Custom commands have been merged into skills"). Both kinds carry the same vendor frontmatter today; skill-map keeps them as distinct `IProviderKind`s in the registry (different UI presentation, different `defaultRefreshAction`) but extends the same base via `allOf` + `$ref` so the field catalog is single-sourced. Field naming is reproduced verbatim from Anthropic \u2014 a deliberate mix of kebab-case (`argument-hint`, `disable-model-invocation`, `user-invocable`, `allowed-tools`), snake_case (`when_to_use`), and camelCase. `additionalProperties: true` so future Anthropic additions flow through unchanged until this schema catches up.',
|
|
264
264
|
allOf: [
|
|
265
|
-
{ $ref: "https://skill-map.
|
|
265
|
+
{ $ref: "https://skill-map.ai/spec/v0/frontmatter/base.schema.json" }
|
|
266
266
|
],
|
|
267
267
|
type: "object",
|
|
268
268
|
additionalProperties: true,
|
|
@@ -297,6 +297,13 @@ var skill_base_schema_default = {
|
|
|
297
297
|
],
|
|
298
298
|
description: "Tools pre-approved for this skill (no per-use permission prompt). Argument-scoped patterns supported (`Bash(git add *)`)."
|
|
299
299
|
},
|
|
300
|
+
"disallowed-tools": {
|
|
301
|
+
oneOf: [
|
|
302
|
+
{ type: "string" },
|
|
303
|
+
{ type: "array", items: { type: "string" } }
|
|
304
|
+
],
|
|
305
|
+
description: "Denylist sibling of `allowed-tools`: tools removed from the available pool while this skill / command is active (the restriction clears on the next user message). Accepts a space- or comma-separated string or a YAML list. Source: https://code.claude.com/docs/en/skills.md."
|
|
306
|
+
},
|
|
300
307
|
model: {
|
|
301
308
|
type: "string",
|
|
302
309
|
description: "Model alias (`sonnet`, `opus`, `haiku`), full Claude id, or the literal `inherit` to defer to the parent session's model."
|
|
@@ -337,11 +344,11 @@ var skill_base_schema_default = {
|
|
|
337
344
|
// plugins/claude/providers/claude/schemas/agent.schema.json
|
|
338
345
|
var agent_schema_default = {
|
|
339
346
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
340
|
-
$id: "https://skill-map.
|
|
347
|
+
$id: "https://skill-map.ai/providers/claude/v1/frontmatter/agent.schema.json",
|
|
341
348
|
title: "FrontmatterAgent",
|
|
342
|
-
description: "Frontmatter shape for nodes classified as `agent` by the Claude Provider. Mirrors Anthropic's documented agent frontmatter verbatim (https://code.claude.com/docs/en/agents.md): `name` and `description` come from the spec base; this schema adds the 14 vendor-specific fields. skill-map AGGREGATES the vendor spec, it does not curate it \u2014 keys are reproduced exactly as Anthropic publishes them (mix of camelCase and snake_case). `additionalProperties: true` so future Anthropic additions flow through unchanged until this schema catches up.",
|
|
349
|
+
description: "Frontmatter shape for nodes classified as `agent` by the Claude Provider. Mirrors Anthropic's documented agent frontmatter verbatim (https://code.claude.com/docs/en/sub-agents.md): `name` and `description` come from the spec base; this schema adds the 14 vendor-specific fields. skill-map AGGREGATES the vendor spec, it does not curate it \u2014 keys are reproduced exactly as Anthropic publishes them (mix of camelCase and snake_case). `additionalProperties: true` so future Anthropic additions flow through unchanged until this schema catches up.",
|
|
343
350
|
allOf: [
|
|
344
|
-
{ $ref: "https://skill-map.
|
|
351
|
+
{ $ref: "https://skill-map.ai/spec/v0/frontmatter/base.schema.json" }
|
|
345
352
|
],
|
|
346
353
|
type: "object",
|
|
347
354
|
additionalProperties: true,
|
|
@@ -363,7 +370,7 @@ var agent_schema_default = {
|
|
|
363
370
|
permissionMode: {
|
|
364
371
|
type: "string",
|
|
365
372
|
enum: ["default", "acceptEdits", "auto", "dontAsk", "bypassPermissions", "plan"],
|
|
366
|
-
description: "How the agent handles permission prompts. See https://code.claude.com/docs/en/agents.md."
|
|
373
|
+
description: "How the agent handles permission prompts. See https://code.claude.com/docs/en/sub-agents.md."
|
|
367
374
|
},
|
|
368
375
|
maxTurns: {
|
|
369
376
|
type: "integer",
|
|
@@ -418,11 +425,11 @@ var agent_schema_default = {
|
|
|
418
425
|
// plugins/claude/providers/claude/schemas/command.schema.json
|
|
419
426
|
var command_schema_default = {
|
|
420
427
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
421
|
-
$id: "https://skill-map.
|
|
428
|
+
$id: "https://skill-map.ai/providers/claude/v1/frontmatter/command.schema.json",
|
|
422
429
|
title: "FrontmatterCommand",
|
|
423
430
|
description: "Frontmatter shape for nodes classified as `command` by the Claude Provider. Today identical to `skill` per Anthropic's documented merger (https://code.claude.com/docs/en/skills.md \u2014 \"Custom commands have been merged into skills\"). Both extend the shared `skill-base.schema.json` via the same `allOf` pattern. The two are kept SPLIT (not aliased) because skill-map's registry differentiates them in `IProviderKind.ui` (separate label / icon / color) and `defaultRefreshAction`. Splitting also reserves room for future divergence. No command-only fields today; `additionalProperties: true` so the file is ready for them.",
|
|
424
431
|
allOf: [
|
|
425
|
-
{ $ref: "https://skill-map.
|
|
432
|
+
{ $ref: "https://skill-map.ai/providers/claude/v1/frontmatter/skill-base.schema.json" }
|
|
426
433
|
],
|
|
427
434
|
type: "object",
|
|
428
435
|
additionalProperties: true,
|
|
@@ -498,7 +505,7 @@ var claudeProvider = {
|
|
|
498
505
|
icon: { kind: "pi", id: "pi-user" }
|
|
499
506
|
},
|
|
500
507
|
// `frontmatter.name` is the documented canonical identifier
|
|
501
|
-
// (https://code.claude.com/docs/en/agents.md); `filename-basename`
|
|
508
|
+
// (https://code.claude.com/docs/en/sub-agents.md); `filename-basename`
|
|
502
509
|
// is a graceful fallback for agents authored without an explicit
|
|
503
510
|
// `name:` field, the file at `.claude/agents/<id>.md` resolves
|
|
504
511
|
// `@<id>` even when frontmatter is partial.
|
|
@@ -981,11 +988,11 @@ var antigravityProvider = {
|
|
|
981
988
|
// plugins/openai/providers/openai/schemas/agent.schema.json
|
|
982
989
|
var agent_schema_default2 = {
|
|
983
990
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
984
|
-
$id: "https://skill-map.
|
|
991
|
+
$id: "https://skill-map.ai/providers/openai/v1/frontmatter/agent.schema.json",
|
|
985
992
|
title: "FrontmatterCodexAgent",
|
|
986
993
|
description: "Frontmatter shape for nodes classified as `agent` by the OpenAI Codex Provider. Codex sub-agents live as TOML files under `.codex/agents/<name>.toml`; the entire file IS the agent definition (no markdown body). The TOML parser feeds the parsed root object into `frontmatter`, so this schema validates the same shape skill-map's other providers carry on per-kind frontmatter. Mirrors Codex's documented sub-agent fields (https://github.com/openai/codex) with `additionalProperties: true` so future additions flow through unchanged.",
|
|
987
994
|
allOf: [
|
|
988
|
-
{ $ref: "https://skill-map.
|
|
995
|
+
{ $ref: "https://skill-map.ai/spec/v0/frontmatter/base.schema.json" }
|
|
989
996
|
],
|
|
990
997
|
type: "object",
|
|
991
998
|
additionalProperties: true,
|
|
@@ -1088,15 +1095,34 @@ var openaiProvider = {
|
|
|
1088
1095
|
// plugins/agent-skills/providers/agent-skills/schemas/skill.schema.json
|
|
1089
1096
|
var skill_schema_default2 = {
|
|
1090
1097
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1091
|
-
$id: "https://skill-map.
|
|
1098
|
+
$id: "https://skill-map.ai/providers/agent-skills/v1/frontmatter/skill.schema.json",
|
|
1092
1099
|
title: "FrontmatterAgentSkillsSkill",
|
|
1093
|
-
description: "Frontmatter shape for nodes classified as `skill` by the neutral `agent-skills` Provider
|
|
1100
|
+
description: "Frontmatter shape for nodes classified as `skill` by the neutral `agent-skills` Provider, Agent Skills delivered as `SKILL.md` files at the open-standard path `.agents/skills/<name>/SKILL.md`. Jointly adopted by Anthropic, OpenAI (Codex), and Google (Gemini); the path is vendor-neutral so no single Provider should own it. Required fields are `name` and `description` (from spec base). The standard's optional frontmatter fields are declared below, mirrored verbatim from https://agentskills.io/specification: `license`, `compatibility`, `metadata`, and the experimental `allowed-tools`. `additionalProperties: true` so any future standard field flows through unchanged until this schema catches up.",
|
|
1094
1101
|
allOf: [
|
|
1095
|
-
{ $ref: "https://skill-map.
|
|
1102
|
+
{ $ref: "https://skill-map.ai/spec/v0/frontmatter/base.schema.json" }
|
|
1096
1103
|
],
|
|
1097
1104
|
type: "object",
|
|
1098
1105
|
additionalProperties: true,
|
|
1099
|
-
properties: {
|
|
1106
|
+
properties: {
|
|
1107
|
+
license: {
|
|
1108
|
+
type: "string",
|
|
1109
|
+
description: "License applied to the skill: a license name (e.g. `Apache-2.0`) or a reference to a bundled license file. Source: https://agentskills.io/specification."
|
|
1110
|
+
},
|
|
1111
|
+
compatibility: {
|
|
1112
|
+
type: "string",
|
|
1113
|
+
maxLength: 500,
|
|
1114
|
+
description: "Environment requirements (intended product, required system packages, network access, etc.). Most skills omit it. Max 500 characters. Source: https://agentskills.io/specification."
|
|
1115
|
+
},
|
|
1116
|
+
metadata: {
|
|
1117
|
+
type: "object",
|
|
1118
|
+
additionalProperties: { type: "string" },
|
|
1119
|
+
description: "Arbitrary string-keyed, string-valued map for client-defined metadata not covered by the standard. Source: https://agentskills.io/specification."
|
|
1120
|
+
},
|
|
1121
|
+
"allowed-tools": {
|
|
1122
|
+
type: "string",
|
|
1123
|
+
description: "Space-separated list of pre-approved tools the skill may run (e.g. `Bash(git:*) Read`). Experimental in the open standard; support varies between agent implementations. Source: https://agentskills.io/specification."
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1100
1126
|
};
|
|
1101
1127
|
|
|
1102
1128
|
// plugins/agent-skills/providers/agent-skills/index.ts
|
|
@@ -1150,11 +1176,11 @@ var agentSkillsProvider = {
|
|
|
1150
1176
|
// plugins/core/providers/core-markdown/schemas/markdown.schema.json
|
|
1151
1177
|
var markdown_schema_default = {
|
|
1152
1178
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1153
|
-
$id: "https://skill-map.
|
|
1179
|
+
$id: "https://skill-map.ai/providers/core/v1/frontmatter/markdown.schema.json",
|
|
1154
1180
|
title: "FrontmatterMarkdown",
|
|
1155
1181
|
description: "Frontmatter shape for nodes classified as `markdown` by the built-in `core/markdown` Provider, the universal fallback for any markdown file no vendor-specific Provider claims (Claude, OpenAI Codex, agent-skills, plus the metadata-only Antigravity bundle). The kind is named after the format because the file is a generic fallback; format-named kinds apply only as the generic fallback, a TOML file that IS a Codex agent still classifies as `agent`, not `toml`. Extends the spec's universal `frontmatter/base.schema.json` via $ref-by-$id with no additional fields. Ownership relocated from the Claude Provider in spec 0.18.0, markdown is provider-agnostic and lives under `core` so adding new vendor Providers does not require choosing which one owns the universal fallback.",
|
|
1156
1182
|
allOf: [
|
|
1157
|
-
{ $ref: "https://skill-map.
|
|
1183
|
+
{ $ref: "https://skill-map.ai/spec/v0/frontmatter/base.schema.json" }
|
|
1158
1184
|
],
|
|
1159
1185
|
type: "object",
|
|
1160
1186
|
additionalProperties: true
|
|
@@ -2935,10 +2961,10 @@ function buildSchemaValidators() {
|
|
|
2935
2961
|
hook: "extension-hook"
|
|
2936
2962
|
};
|
|
2937
2963
|
const pluginManifestValidator = ajv.compile({
|
|
2938
|
-
$ref: "https://skill-map.
|
|
2964
|
+
$ref: "https://skill-map.ai/spec/v0/plugins-registry.schema.json#/$defs/PluginManifest"
|
|
2939
2965
|
});
|
|
2940
2966
|
const contributionValidators = /* @__PURE__ */ new Map();
|
|
2941
|
-
const VIEW_SLOTS_ID = "https://skill-map.
|
|
2967
|
+
const VIEW_SLOTS_ID = "https://skill-map.ai/spec/v0/view-slots.schema.json";
|
|
2942
2968
|
function getContributionValidator(slot) {
|
|
2943
2969
|
if (!KNOWN_SLOT_NAMES.has(slot)) return null;
|
|
2944
2970
|
const existing = contributionValidators.get(slot);
|
|
@@ -3920,11 +3946,11 @@ var UPDATE_CHECK_TEXTS = {
|
|
|
3920
3946
|
// package.json
|
|
3921
3947
|
var package_default = {
|
|
3922
3948
|
name: "@skill-map/cli",
|
|
3923
|
-
version: "0.
|
|
3949
|
+
version: "0.43.0",
|
|
3924
3950
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
3925
3951
|
license: "MIT",
|
|
3926
3952
|
type: "module",
|
|
3927
|
-
homepage: "https://skill-map.
|
|
3953
|
+
homepage: "https://skill-map.ai",
|
|
3928
3954
|
repository: {
|
|
3929
3955
|
type: "git",
|
|
3930
3956
|
url: "git+https://github.com/crystian/skill-map.git",
|
|
@@ -4352,40 +4378,40 @@ var updateCheckHook = {
|
|
|
4352
4378
|
};
|
|
4353
4379
|
|
|
4354
4380
|
// plugins/built-ins.ts
|
|
4355
|
-
var claudeProvider2 = { ...claudeProvider, pluginId: "claude", version: "0.
|
|
4356
|
-
var atDirectiveExtractor2 = { ...atDirectiveExtractor, pluginId: "claude", version: "0.
|
|
4357
|
-
var slashCommandExtractor2 = { ...slashCommandExtractor, pluginId: "claude", version: "0.
|
|
4358
|
-
var antigravityProvider2 = { ...antigravityProvider, pluginId: "antigravity", version: "0.
|
|
4359
|
-
var openaiProvider2 = { ...openaiProvider, pluginId: "openai", version: "0.
|
|
4360
|
-
var agentSkillsProvider2 = { ...agentSkillsProvider, pluginId: "agent-skills", version: "0.
|
|
4361
|
-
var coreMarkdownProvider2 = { ...coreMarkdownProvider, pluginId: "core", version: "0.
|
|
4362
|
-
var annotationsExtractor2 = { ...annotationsExtractor, pluginId: "core", version: "0.
|
|
4363
|
-
var externalUrlCounterExtractor2 = { ...externalUrlCounterExtractor, pluginId: "core", version: "0.
|
|
4364
|
-
var markdownLinkExtractor2 = { ...markdownLinkExtractor, pluginId: "core", version: "0.
|
|
4365
|
-
var mcpToolsExtractor2 = { ...mcpToolsExtractor, pluginId: "core", version: "0.
|
|
4366
|
-
var toolsCounterExtractor2 = { ...toolsCounterExtractor, pluginId: "core", version: "0.
|
|
4367
|
-
var annotationFieldUnknownAnalyzer2 = { ...annotationFieldUnknownAnalyzer, pluginId: "core", version: "0.
|
|
4368
|
-
var annotationOrphanAnalyzer2 = { ...annotationOrphanAnalyzer, pluginId: "core", version: "0.
|
|
4369
|
-
var annotationStaleAnalyzer2 = { ...annotationStaleAnalyzer, pluginId: "core", version: "0.
|
|
4370
|
-
var contributionOrphanAnalyzer2 = { ...contributionOrphanAnalyzer, pluginId: "core", version: "0.
|
|
4371
|
-
var issueCounterAnalyzer2 = { ...issueCounterAnalyzer, pluginId: "core", version: "0.
|
|
4372
|
-
var jobFileOrphanAnalyzer2 = { ...jobFileOrphanAnalyzer, pluginId: "core", version: "0.
|
|
4373
|
-
var linkConflictAnalyzer2 = { ...linkConflictAnalyzer, pluginId: "core", version: "0.
|
|
4374
|
-
var linkCounterAnalyzer2 = { ...linkCounterAnalyzer, pluginId: "core", version: "0.
|
|
4375
|
-
var linkSelfLoopAnalyzer2 = { ...linkSelfLoopAnalyzer, pluginId: "core", version: "0.
|
|
4376
|
-
var nameReservedAnalyzer2 = { ...nameReservedAnalyzer, pluginId: "core", version: "0.
|
|
4377
|
-
var nodeStabilityAnalyzer2 = { ...nodeStabilityAnalyzer, pluginId: "core", version: "0.
|
|
4378
|
-
var nodeSupersededAnalyzer2 = { ...nodeSupersededAnalyzer, pluginId: "core", version: "0.
|
|
4379
|
-
var referenceBrokenAnalyzer2 = { ...referenceBrokenAnalyzer, pluginId: "core", version: "0.
|
|
4380
|
-
var referenceRedundantAnalyzer2 = { ...referenceRedundantAnalyzer, pluginId: "core", version: "0.
|
|
4381
|
-
var schemaViolationAnalyzer2 = { ...schemaViolationAnalyzer, pluginId: "core", version: "0.
|
|
4382
|
-
var signalCollisionAnalyzer2 = { ...signalCollisionAnalyzer, pluginId: "core", version: "0.
|
|
4383
|
-
var triggerCollisionAnalyzer2 = { ...triggerCollisionAnalyzer, pluginId: "core", version: "0.
|
|
4384
|
-
var asciiFormatter2 = { ...asciiFormatter, pluginId: "core", version: "0.
|
|
4385
|
-
var jsonFormatter2 = { ...jsonFormatter, pluginId: "core", version: "0.
|
|
4386
|
-
var nodeBumpAction2 = { ...nodeBumpAction, pluginId: "core", version: "0.
|
|
4387
|
-
var nodeSupersedeAction2 = { ...nodeSupersedeAction, pluginId: "core", version: "0.
|
|
4388
|
-
var updateCheckHook2 = { ...updateCheckHook, pluginId: "core", version: "0.
|
|
4381
|
+
var claudeProvider2 = { ...claudeProvider, pluginId: "claude", version: "0.43.0" };
|
|
4382
|
+
var atDirectiveExtractor2 = { ...atDirectiveExtractor, pluginId: "claude", version: "0.43.0" };
|
|
4383
|
+
var slashCommandExtractor2 = { ...slashCommandExtractor, pluginId: "claude", version: "0.43.0" };
|
|
4384
|
+
var antigravityProvider2 = { ...antigravityProvider, pluginId: "antigravity", version: "0.43.0" };
|
|
4385
|
+
var openaiProvider2 = { ...openaiProvider, pluginId: "openai", version: "0.43.0" };
|
|
4386
|
+
var agentSkillsProvider2 = { ...agentSkillsProvider, pluginId: "agent-skills", version: "0.43.0" };
|
|
4387
|
+
var coreMarkdownProvider2 = { ...coreMarkdownProvider, pluginId: "core", version: "0.43.0" };
|
|
4388
|
+
var annotationsExtractor2 = { ...annotationsExtractor, pluginId: "core", version: "0.43.0" };
|
|
4389
|
+
var externalUrlCounterExtractor2 = { ...externalUrlCounterExtractor, pluginId: "core", version: "0.43.0" };
|
|
4390
|
+
var markdownLinkExtractor2 = { ...markdownLinkExtractor, pluginId: "core", version: "0.43.0" };
|
|
4391
|
+
var mcpToolsExtractor2 = { ...mcpToolsExtractor, pluginId: "core", version: "0.43.0" };
|
|
4392
|
+
var toolsCounterExtractor2 = { ...toolsCounterExtractor, pluginId: "core", version: "0.43.0" };
|
|
4393
|
+
var annotationFieldUnknownAnalyzer2 = { ...annotationFieldUnknownAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4394
|
+
var annotationOrphanAnalyzer2 = { ...annotationOrphanAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4395
|
+
var annotationStaleAnalyzer2 = { ...annotationStaleAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4396
|
+
var contributionOrphanAnalyzer2 = { ...contributionOrphanAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4397
|
+
var issueCounterAnalyzer2 = { ...issueCounterAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4398
|
+
var jobFileOrphanAnalyzer2 = { ...jobFileOrphanAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4399
|
+
var linkConflictAnalyzer2 = { ...linkConflictAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4400
|
+
var linkCounterAnalyzer2 = { ...linkCounterAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4401
|
+
var linkSelfLoopAnalyzer2 = { ...linkSelfLoopAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4402
|
+
var nameReservedAnalyzer2 = { ...nameReservedAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4403
|
+
var nodeStabilityAnalyzer2 = { ...nodeStabilityAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4404
|
+
var nodeSupersededAnalyzer2 = { ...nodeSupersededAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4405
|
+
var referenceBrokenAnalyzer2 = { ...referenceBrokenAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4406
|
+
var referenceRedundantAnalyzer2 = { ...referenceRedundantAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4407
|
+
var schemaViolationAnalyzer2 = { ...schemaViolationAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4408
|
+
var signalCollisionAnalyzer2 = { ...signalCollisionAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4409
|
+
var triggerCollisionAnalyzer2 = { ...triggerCollisionAnalyzer, pluginId: "core", version: "0.43.0" };
|
|
4410
|
+
var asciiFormatter2 = { ...asciiFormatter, pluginId: "core", version: "0.43.0" };
|
|
4411
|
+
var jsonFormatter2 = { ...jsonFormatter, pluginId: "core", version: "0.43.0" };
|
|
4412
|
+
var nodeBumpAction2 = { ...nodeBumpAction, pluginId: "core", version: "0.43.0" };
|
|
4413
|
+
var nodeSupersedeAction2 = { ...nodeSupersedeAction, pluginId: "core", version: "0.43.0" };
|
|
4414
|
+
var updateCheckHook2 = { ...updateCheckHook, pluginId: "core", version: "0.43.0" };
|
|
4389
4415
|
var builtInBundles = [
|
|
4390
4416
|
{
|
|
4391
4417
|
id: "claude",
|
|
@@ -7444,8 +7470,7 @@ async function replaceAllScanTags(trx, records, livePaths = /* @__PURE__ */ new
|
|
|
7444
7470
|
if (records.length === 0) return;
|
|
7445
7471
|
const rows = records.map((r) => ({
|
|
7446
7472
|
nodePath: r.nodePath,
|
|
7447
|
-
tag: r.tag
|
|
7448
|
-
source: r.source
|
|
7473
|
+
tag: r.tag
|
|
7449
7474
|
}));
|
|
7450
7475
|
const BATCH = 300;
|
|
7451
7476
|
for (let i = 0; i < rows.length; i += BATCH) {
|
|
@@ -7453,18 +7478,16 @@ async function replaceAllScanTags(trx, records, livePaths = /* @__PURE__ */ new
|
|
|
7453
7478
|
}
|
|
7454
7479
|
}
|
|
7455
7480
|
async function loadTagsForNode(db, nodePath) {
|
|
7456
|
-
const rows = await db.selectFrom("scan_node_tags").select(["nodePath", "tag"
|
|
7457
|
-
return rows.map((r) => ({ nodePath: r.nodePath, tag: r.tag
|
|
7481
|
+
const rows = await db.selectFrom("scan_node_tags").select(["nodePath", "tag"]).where("nodePath", "=", nodePath).orderBy("tag", "asc").execute();
|
|
7482
|
+
return rows.map((r) => ({ nodePath: r.nodePath, tag: r.tag }));
|
|
7458
7483
|
}
|
|
7459
7484
|
async function loadTagsForPaths(db, nodePaths) {
|
|
7460
7485
|
if (nodePaths.length === 0) return [];
|
|
7461
|
-
const rows = await db.selectFrom("scan_node_tags").select(["nodePath", "tag"
|
|
7462
|
-
return rows.map((r) => ({ nodePath: r.nodePath, tag: r.tag
|
|
7486
|
+
const rows = await db.selectFrom("scan_node_tags").select(["nodePath", "tag"]).where("nodePath", "in", [...nodePaths]).orderBy("tag", "asc").execute();
|
|
7487
|
+
return rows.map((r) => ({ nodePath: r.nodePath, tag: r.tag }));
|
|
7463
7488
|
}
|
|
7464
|
-
async function findNodesByTag(db, tag
|
|
7465
|
-
|
|
7466
|
-
if (source !== void 0) q = q.where("source", "=", source);
|
|
7467
|
-
const rows = await q.distinct().orderBy("nodePath", "asc").execute();
|
|
7489
|
+
async function findNodesByTag(db, tag) {
|
|
7490
|
+
const rows = await db.selectFrom("scan_node_tags").select("nodePath").where("tag", "=", tag).distinct().orderBy("nodePath", "asc").execute();
|
|
7468
7491
|
return rows.map((r) => r.nodePath);
|
|
7469
7492
|
}
|
|
7470
7493
|
|
|
@@ -7662,19 +7685,18 @@ function pickIntegerVersion(v) {
|
|
|
7662
7685
|
function nodesToTagRecords(nodes) {
|
|
7663
7686
|
const records = [];
|
|
7664
7687
|
for (const node of nodes) {
|
|
7665
|
-
pushTagRecords(records, node.path, node.
|
|
7666
|
-
pushTagRecords(records, node.path, node.sidecar?.annotations?.["tags"], "user");
|
|
7688
|
+
pushTagRecords(records, node.path, node.sidecar?.annotations?.["tags"]);
|
|
7667
7689
|
}
|
|
7668
7690
|
return records;
|
|
7669
7691
|
}
|
|
7670
|
-
function pushTagRecords(out, nodePath, raw
|
|
7692
|
+
function pushTagRecords(out, nodePath, raw) {
|
|
7671
7693
|
if (!Array.isArray(raw)) return;
|
|
7672
7694
|
const seen = /* @__PURE__ */ new Set();
|
|
7673
7695
|
for (const item of raw) {
|
|
7674
7696
|
if (typeof item !== "string" || item.length === 0) continue;
|
|
7675
7697
|
if (seen.has(item)) continue;
|
|
7676
7698
|
seen.add(item);
|
|
7677
|
-
out.push({ nodePath, tag: item
|
|
7699
|
+
out.push({ nodePath, tag: item });
|
|
7678
7700
|
}
|
|
7679
7701
|
}
|
|
7680
7702
|
function linkToRow(link) {
|
|
@@ -7915,7 +7937,7 @@ var SqliteStorageAdapter = class {
|
|
|
7915
7937
|
this.tags = {
|
|
7916
7938
|
listForNode: (nodePath) => loadTagsForNode(this.db, nodePath),
|
|
7917
7939
|
listForPaths: (paths) => loadTagsForPaths(this.db, paths),
|
|
7918
|
-
findNodes: (tag
|
|
7940
|
+
findNodes: (tag) => findNodesByTag(this.db, tag)
|
|
7919
7941
|
};
|
|
7920
7942
|
this.issues = {
|
|
7921
7943
|
listAll: () => listAllIssues(this.db),
|
|
@@ -12618,9 +12640,22 @@ var DbRestoreCommand = class extends SmCommand {
|
|
|
12618
12640
|
};
|
|
12619
12641
|
|
|
12620
12642
|
// cli/commands/db/reset.ts
|
|
12621
|
-
import { rm as rm2 } from "fs/promises";
|
|
12622
12643
|
import { DatabaseSync as DatabaseSync5 } from "node:sqlite";
|
|
12623
12644
|
import { Command as Command8, Option as Option8 } from "clipanion";
|
|
12645
|
+
|
|
12646
|
+
// core/sqlite/db-files.ts
|
|
12647
|
+
import { existsSync as existsSync19 } from "fs";
|
|
12648
|
+
import { rm as rm2 } from "fs/promises";
|
|
12649
|
+
var DB_FILE_SUFFIXES = ["", "-wal", "-shm"];
|
|
12650
|
+
async function removeDbFiles(dbPath) {
|
|
12651
|
+
if (dbPath === ":memory:") return;
|
|
12652
|
+
for (const suffix of DB_FILE_SUFFIXES) {
|
|
12653
|
+
const p = `${dbPath}${suffix}`;
|
|
12654
|
+
if (existsSync19(p)) await rm2(p);
|
|
12655
|
+
}
|
|
12656
|
+
}
|
|
12657
|
+
|
|
12658
|
+
// cli/commands/db/reset.ts
|
|
12624
12659
|
var DbResetCommand = class extends SmCommand {
|
|
12625
12660
|
static paths = [["db", "reset"]];
|
|
12626
12661
|
static usage = Command8.Usage({
|
|
@@ -12680,10 +12715,7 @@ var DbResetCommand = class extends SmCommand {
|
|
|
12680
12715
|
return ExitCode.Error;
|
|
12681
12716
|
}
|
|
12682
12717
|
}
|
|
12683
|
-
|
|
12684
|
-
const p = `${path}${suffix}`;
|
|
12685
|
-
if (await pathExists(p)) await rm2(p);
|
|
12686
|
-
}
|
|
12718
|
+
await removeDbFiles(path);
|
|
12687
12719
|
const ansiHard = this.ansiFor("stdout");
|
|
12688
12720
|
this.printer.data(
|
|
12689
12721
|
tx(DB_TEXTS.resetHardDeleted, {
|
|
@@ -14424,7 +14456,7 @@ import { join as join17 } from "path";
|
|
|
14424
14456
|
import { Command as Command17, Option as Option16 } from "clipanion";
|
|
14425
14457
|
|
|
14426
14458
|
// kernel/orchestrator/index.ts
|
|
14427
|
-
import { existsSync as
|
|
14459
|
+
import { existsSync as existsSync22, statSync as statSync6 } from "fs";
|
|
14428
14460
|
import { isAbsolute as isAbsolute7, resolve as resolve28 } from "path";
|
|
14429
14461
|
import { Tiktoken as Tiktoken2 } from "js-tiktoken/lite";
|
|
14430
14462
|
import cl100k_base from "js-tiktoken/ranks/cl100k_base";
|
|
@@ -15471,7 +15503,7 @@ function computeDriftStatus(args2) {
|
|
|
15471
15503
|
}
|
|
15472
15504
|
|
|
15473
15505
|
// kernel/sidecar/discover-orphans.ts
|
|
15474
|
-
import { existsSync as
|
|
15506
|
+
import { existsSync as existsSync20, readdirSync as readdirSync7, statSync as statSync5 } from "fs";
|
|
15475
15507
|
import { join as join13, relative as relative4, sep as sep4 } from "path";
|
|
15476
15508
|
function discoverOrphanSidecars(roots, shouldSkip) {
|
|
15477
15509
|
const out = [];
|
|
@@ -15499,7 +15531,7 @@ function walk(root, current, shouldSkip, out) {
|
|
|
15499
15531
|
if (!entry.isFile()) continue;
|
|
15500
15532
|
if (!entry.name.endsWith(".sm")) continue;
|
|
15501
15533
|
const expectedMd = `${full.slice(0, -".sm".length)}.md`;
|
|
15502
|
-
if (
|
|
15534
|
+
if (existsSync20(expectedMd) && safeIsFile(expectedMd)) continue;
|
|
15503
15535
|
out.push({ sidecarPath: full, relativePath: rel, expectedMdPath: expectedMd });
|
|
15504
15536
|
}
|
|
15505
15537
|
}
|
|
@@ -15513,7 +15545,7 @@ function safeIsFile(path) {
|
|
|
15513
15545
|
|
|
15514
15546
|
// kernel/orchestrator/node-build.ts
|
|
15515
15547
|
import { createHash } from "crypto";
|
|
15516
|
-
import { existsSync as
|
|
15548
|
+
import { existsSync as existsSync21 } from "fs";
|
|
15517
15549
|
import { isAbsolute as isAbsolute6, resolve as resolvePath } from "path";
|
|
15518
15550
|
import "js-tiktoken/lite";
|
|
15519
15551
|
import yaml4 from "js-yaml";
|
|
@@ -15677,11 +15709,11 @@ function resolveSidecarOverlay(relativePath2, nodePathForIssue, roots, liveBodyH
|
|
|
15677
15709
|
}
|
|
15678
15710
|
function resolveAbsoluteMdPath(relativePath2, roots) {
|
|
15679
15711
|
if (isAbsolute6(relativePath2)) {
|
|
15680
|
-
return
|
|
15712
|
+
return existsSync21(relativePath2) ? relativePath2 : null;
|
|
15681
15713
|
}
|
|
15682
15714
|
for (const root of roots) {
|
|
15683
15715
|
const candidate = resolvePath(root, relativePath2);
|
|
15684
|
-
if (
|
|
15716
|
+
if (existsSync21(candidate)) return candidate;
|
|
15685
15717
|
}
|
|
15686
15718
|
return null;
|
|
15687
15719
|
}
|
|
@@ -16246,7 +16278,7 @@ function validateRoots(roots) {
|
|
|
16246
16278
|
throw new Error(ORCHESTRATOR_TEXTS.runScanRootEmptyArray);
|
|
16247
16279
|
}
|
|
16248
16280
|
for (const root of roots) {
|
|
16249
|
-
if (!
|
|
16281
|
+
if (!existsSync22(root) || !statSync6(root).isDirectory()) {
|
|
16250
16282
|
throw new Error(tx(ORCHESTRATOR_TEXTS.runScanRootMissing, { root }));
|
|
16251
16283
|
}
|
|
16252
16284
|
}
|
|
@@ -16255,7 +16287,7 @@ function resolveActiveProviderOption(optionValue, roots, providers) {
|
|
|
16255
16287
|
if (optionValue !== void 0) return optionValue;
|
|
16256
16288
|
for (const root of roots) {
|
|
16257
16289
|
const absRoot = isAbsolute7(root) ? root : resolve28(root);
|
|
16258
|
-
if (!
|
|
16290
|
+
if (!existsSync22(absRoot)) continue;
|
|
16259
16291
|
const detected = resolveActiveProvider(absRoot, providers).resolved;
|
|
16260
16292
|
if (detected !== null) return detected;
|
|
16261
16293
|
}
|
|
@@ -16895,6 +16927,99 @@ async function promptForLens(detected, stdin, stderr, warnGlyph) {
|
|
|
16895
16927
|
}
|
|
16896
16928
|
}
|
|
16897
16929
|
|
|
16930
|
+
// core/sqlite/db-drift-reset.ts
|
|
16931
|
+
import { existsSync as existsSync23 } from "fs";
|
|
16932
|
+
import { createInterface as createInterface3 } from "readline";
|
|
16933
|
+
import { DatabaseSync as DatabaseSync7 } from "node:sqlite";
|
|
16934
|
+
|
|
16935
|
+
// core/sqlite/i18n/db-drift.texts.ts
|
|
16936
|
+
var DB_DRIFT_TEXTS = {
|
|
16937
|
+
// Interactive confirm (TTY `sm scan`, no `--yes`). The block is
|
|
16938
|
+
// written to stderr, then the question line drives `readline`.
|
|
16939
|
+
driftPrompt: "{{glyph}} The local cache was built by skill-map {{dbVersion}} and you are on {{currentVersion}}.\n {{hint}}\n",
|
|
16940
|
+
driftPromptHint: "Pre-1.0 the DB is a derived cache (your .sm sidecars hold the real data); it cannot be carried across a version change and has to be rebuilt.",
|
|
16941
|
+
driftPromptQuestion: "Delete the local cache and rebuild it on this scan? [y/N] ",
|
|
16942
|
+
// Receipt after the rebuild (printed by the scan / refresh path).
|
|
16943
|
+
driftReset: "{{glyph}} Local cache rebuilt: it was written by skill-map {{dbVersion}}, you are on {{currentVersion}}.\n {{hint}}\n",
|
|
16944
|
+
driftResetHint: "The DB was deleted and is being regenerated by this scan; .sm sidecars were not touched.",
|
|
16945
|
+
// Abort headline when the operator declines (wrapped by the caller's
|
|
16946
|
+
// `sm scan: {message}` shell, so it carries no glyph / verb prefix).
|
|
16947
|
+
driftAborted: "cache rebuild declined: the {{dbVersion}} cache cannot be reused on {{currentVersion}}. {{hint}}",
|
|
16948
|
+
driftAbortedHint: "Re-run with --yes, or run `sm db reset --hard` then `sm scan`."
|
|
16949
|
+
};
|
|
16950
|
+
|
|
16951
|
+
// core/sqlite/db-drift-reset.ts
|
|
16952
|
+
async function maybeResetOnDrift(dbPath, policy) {
|
|
16953
|
+
const dbVersion = readScannedByVersion(dbPath);
|
|
16954
|
+
if (dbVersion === null) return { kind: "no-drift" };
|
|
16955
|
+
const skew = classifyVersionSkew(dbVersion, policy.currentVersion);
|
|
16956
|
+
if (skew.kind === "ok" || skew.kind === "no-meta") return { kind: "no-drift" };
|
|
16957
|
+
const confirmed = await confirmDriftReset(dbVersion, policy);
|
|
16958
|
+
if (!confirmed) {
|
|
16959
|
+
return { kind: "aborted", dbVersion, currentVersion: policy.currentVersion };
|
|
16960
|
+
}
|
|
16961
|
+
await removeDbFiles(dbPath);
|
|
16962
|
+
renderResetReceipt(dbVersion, policy);
|
|
16963
|
+
return { kind: "reset", dbVersion, currentVersion: policy.currentVersion };
|
|
16964
|
+
}
|
|
16965
|
+
function readScannedByVersion(dbPath) {
|
|
16966
|
+
if (dbPath === ":memory:" || !existsSync23(dbPath)) return null;
|
|
16967
|
+
let raw = null;
|
|
16968
|
+
try {
|
|
16969
|
+
raw = new DatabaseSync7(dbPath, { readOnly: true });
|
|
16970
|
+
const row = raw.prepare("SELECT scanned_by_version AS v FROM scan_meta LIMIT 1").get();
|
|
16971
|
+
const v = row?.v;
|
|
16972
|
+
return typeof v === "string" && v.length > 0 ? v : null;
|
|
16973
|
+
} catch {
|
|
16974
|
+
return null;
|
|
16975
|
+
} finally {
|
|
16976
|
+
raw?.close();
|
|
16977
|
+
}
|
|
16978
|
+
}
|
|
16979
|
+
async function confirmDriftReset(dbVersion, policy) {
|
|
16980
|
+
if (!shouldPromptForReset(policy)) return true;
|
|
16981
|
+
return askDriftReset(dbVersion, policy);
|
|
16982
|
+
}
|
|
16983
|
+
function shouldPromptForReset(policy) {
|
|
16984
|
+
if (policy.assumeYes) return false;
|
|
16985
|
+
if (!policy.stdin || !policy.stderr) return false;
|
|
16986
|
+
return policy.stdin.isTTY === true;
|
|
16987
|
+
}
|
|
16988
|
+
async function askDriftReset(dbVersion, policy) {
|
|
16989
|
+
const warnGlyph = policy.style?.warnGlyph ?? "\u26A0";
|
|
16990
|
+
const dim = policy.style?.dim ?? ((s) => s);
|
|
16991
|
+
policy.stderr.write(
|
|
16992
|
+
tx(DB_DRIFT_TEXTS.driftPrompt, {
|
|
16993
|
+
glyph: warnGlyph,
|
|
16994
|
+
dbVersion,
|
|
16995
|
+
currentVersion: policy.currentVersion,
|
|
16996
|
+
hint: dim(DB_DRIFT_TEXTS.driftPromptHint)
|
|
16997
|
+
})
|
|
16998
|
+
);
|
|
16999
|
+
const rl = createInterface3({ input: policy.stdin, output: policy.stderr });
|
|
17000
|
+
try {
|
|
17001
|
+
const answer = await new Promise(
|
|
17002
|
+
(resolveP) => rl.question(DB_DRIFT_TEXTS.driftPromptQuestion, resolveP)
|
|
17003
|
+
);
|
|
17004
|
+
return /^y(es)?$/i.test(answer.trim());
|
|
17005
|
+
} finally {
|
|
17006
|
+
rl.close();
|
|
17007
|
+
}
|
|
17008
|
+
}
|
|
17009
|
+
function renderResetReceipt(dbVersion, policy) {
|
|
17010
|
+
if (!policy.printer) return;
|
|
17011
|
+
const warnGlyph = policy.style?.warnGlyph ?? "\u26A0";
|
|
17012
|
+
const dim = policy.style?.dim ?? ((s) => s);
|
|
17013
|
+
policy.printer.warn(
|
|
17014
|
+
tx(DB_DRIFT_TEXTS.driftReset, {
|
|
17015
|
+
glyph: warnGlyph,
|
|
17016
|
+
dbVersion,
|
|
17017
|
+
currentVersion: policy.currentVersion,
|
|
17018
|
+
hint: dim(DB_DRIFT_TEXTS.driftResetHint)
|
|
17019
|
+
})
|
|
17020
|
+
);
|
|
17021
|
+
}
|
|
17022
|
+
|
|
16898
17023
|
// core/runtime/scan-runner.ts
|
|
16899
17024
|
async function runScanForCommand(opts) {
|
|
16900
17025
|
const ctx = opts.ctx ?? defaultRuntimeContext();
|
|
@@ -17092,7 +17217,29 @@ function buildRunScanEmitter(opts) {
|
|
|
17092
17217
|
colorEnabled: opts.colorEnabled === true
|
|
17093
17218
|
});
|
|
17094
17219
|
}
|
|
17220
|
+
async function rebuildOnDrift(opts, dbPath) {
|
|
17221
|
+
const drift = await maybeResetOnDrift(dbPath, {
|
|
17222
|
+
currentVersion: VERSION,
|
|
17223
|
+
assumeYes: opts.yes ?? false,
|
|
17224
|
+
stdin: opts.stdin ?? process.stdin,
|
|
17225
|
+
stderr: opts.stderr,
|
|
17226
|
+
printer: opts.printer,
|
|
17227
|
+
...opts.style ? { style: opts.style } : {}
|
|
17228
|
+
});
|
|
17229
|
+
if (drift.kind !== "aborted") return null;
|
|
17230
|
+
const dim = opts.style?.dim ?? ((s) => s);
|
|
17231
|
+
return {
|
|
17232
|
+
kind: "scan-error",
|
|
17233
|
+
message: tx(DB_DRIFT_TEXTS.driftAborted, {
|
|
17234
|
+
dbVersion: drift.dbVersion,
|
|
17235
|
+
currentVersion: drift.currentVersion,
|
|
17236
|
+
hint: dim(DB_DRIFT_TEXTS.driftAbortedHint)
|
|
17237
|
+
})
|
|
17238
|
+
};
|
|
17239
|
+
}
|
|
17095
17240
|
async function runPersistPath(opts, dbPath, jobsDir, strict, loadPrior, runScanWith, extensions) {
|
|
17241
|
+
const driftError = await rebuildOnDrift(opts, dbPath);
|
|
17242
|
+
if (driftError) return driftError;
|
|
17096
17243
|
let outcome;
|
|
17097
17244
|
try {
|
|
17098
17245
|
outcome = await withSqlite({ databasePath: dbPath }, async (adapter) => {
|
|
@@ -18182,19 +18329,6 @@ import { Command as Command20, Option as Option19 } from "clipanion";
|
|
|
18182
18329
|
var LIST_TEXTS = {
|
|
18183
18330
|
invalidSortBy: '{{glyph}} --sort-by: invalid sort field "{{value}}".\n {{hint}}\n',
|
|
18184
18331
|
invalidSortByHint: "Allowed: {{allowed}}.",
|
|
18185
|
-
/**
|
|
18186
|
-
* §3.1b two-line block. Closed enum: hint enumerates the two valid
|
|
18187
|
-
* values so the operator does not need to re-read `--help`.
|
|
18188
|
-
*/
|
|
18189
|
-
invalidTagSource: '{{glyph}} --tag-source: expected "author" or "user", got "{{value}}".\n {{hint}}\n',
|
|
18190
|
-
invalidTagSourceHint: "Allowed: author, user.",
|
|
18191
|
-
/**
|
|
18192
|
-
* §3.1b two-line block. `--tag-source` is a narrowing filter on
|
|
18193
|
-
* `--tag`; the hint repeats the dependency in operator-actionable
|
|
18194
|
-
* form.
|
|
18195
|
-
*/
|
|
18196
|
-
tagSourceWithoutTag: "{{glyph}} --tag-source requires --tag <name>.\n {{hint}}\n",
|
|
18197
|
-
tagSourceWithoutTagHint: "The source filter narrows tag matches, it does not stand alone. Pass --tag <name> alongside --tag-source.",
|
|
18198
18332
|
noNodesFound: "No nodes found.\n",
|
|
18199
18333
|
// --- renderTable column headers ----------------------------------------
|
|
18200
18334
|
tableHeaderPath: "PATH",
|
|
@@ -18231,9 +18365,8 @@ var ListCommand = class extends SmCommand {
|
|
|
18231
18365
|
Reads from the persisted scan snapshot (scan_nodes). Filters:
|
|
18232
18366
|
--kind <k> restricts to one node kind; --issue keeps only nodes
|
|
18233
18367
|
that touch at least one current issue; --tag <name> keeps only
|
|
18234
|
-
nodes carrying that tag
|
|
18235
|
-
|
|
18236
|
-
narrows to one side).
|
|
18368
|
+
nodes carrying that tag in their \`.sm\` sidecar
|
|
18369
|
+
(\`annotations.tags\`).
|
|
18237
18370
|
|
|
18238
18371
|
--sort-by accepts: path, kind, tokens_total, links_out_count,
|
|
18239
18372
|
links_in_count, external_refs_count. Default: path. --limit N caps
|
|
@@ -18246,8 +18379,7 @@ var ListCommand = class extends SmCommand {
|
|
|
18246
18379
|
["List only agents", "$0 list --kind agent"],
|
|
18247
18380
|
["Top 5 by total tokens", "$0 list --sort-by tokens_total --limit 5"],
|
|
18248
18381
|
["Only nodes with issues, machine-readable", "$0 list --issue --json"],
|
|
18249
|
-
["Filter by tag
|
|
18250
|
-
["Filter by user-only tag", "$0 list --tag wip --tag-source user"]
|
|
18382
|
+
["Filter by tag", "$0 list --tag urgent"]
|
|
18251
18383
|
]
|
|
18252
18384
|
});
|
|
18253
18385
|
kind = Option19.String("--kind", { required: false });
|
|
@@ -18255,7 +18387,6 @@ var ListCommand = class extends SmCommand {
|
|
|
18255
18387
|
sortBy = Option19.String("--sort-by", { required: false });
|
|
18256
18388
|
limit = Option19.String("--limit", { required: false });
|
|
18257
18389
|
tag = Option19.String("--tag", { required: false });
|
|
18258
|
-
tagSource = Option19.String("--tag-source", { required: false });
|
|
18259
18390
|
async run() {
|
|
18260
18391
|
const stderrAnsi = this.ansiFor("stderr");
|
|
18261
18392
|
const flags = this.#parseFlags(stderrAnsi);
|
|
@@ -18274,7 +18405,6 @@ var ListCommand = class extends SmCommand {
|
|
|
18274
18405
|
* resolved values or a precomputed exit code (already printed
|
|
18275
18406
|
* directed errors before returning).
|
|
18276
18407
|
*/
|
|
18277
|
-
// eslint-disable-next-line complexity
|
|
18278
18408
|
#parseFlags(stderrAnsi) {
|
|
18279
18409
|
let sortColumn = "path";
|
|
18280
18410
|
let sortDirection = "asc";
|
|
@@ -18301,30 +18431,7 @@ var ListCommand = class extends SmCommand {
|
|
|
18301
18431
|
if (parsed === null) return { ok: false, exit: ExitCode.Error };
|
|
18302
18432
|
limitValue = parsed;
|
|
18303
18433
|
}
|
|
18304
|
-
|
|
18305
|
-
if (this.tagSource !== void 0) {
|
|
18306
|
-
if (this.tag === void 0) {
|
|
18307
|
-
this.printer.error(
|
|
18308
|
-
tx(LIST_TEXTS.tagSourceWithoutTag, {
|
|
18309
|
-
glyph: stderrAnsi.red("\u2715"),
|
|
18310
|
-
hint: stderrAnsi.dim(LIST_TEXTS.tagSourceWithoutTagHint)
|
|
18311
|
-
})
|
|
18312
|
-
);
|
|
18313
|
-
return { ok: false, exit: ExitCode.Error };
|
|
18314
|
-
}
|
|
18315
|
-
if (this.tagSource !== "author" && this.tagSource !== "user") {
|
|
18316
|
-
this.printer.error(
|
|
18317
|
-
tx(LIST_TEXTS.invalidTagSource, {
|
|
18318
|
-
glyph: stderrAnsi.red("\u2715"),
|
|
18319
|
-
value: this.tagSource,
|
|
18320
|
-
hint: stderrAnsi.dim(LIST_TEXTS.invalidTagSourceHint)
|
|
18321
|
-
})
|
|
18322
|
-
);
|
|
18323
|
-
return { ok: false, exit: ExitCode.Error };
|
|
18324
|
-
}
|
|
18325
|
-
tagSourceValue = this.tagSource;
|
|
18326
|
-
}
|
|
18327
|
-
return { ok: true, sortColumn, sortDirection, limitValue, tagSourceValue };
|
|
18434
|
+
return { ok: true, sortColumn, sortDirection, limitValue };
|
|
18328
18435
|
}
|
|
18329
18436
|
/**
|
|
18330
18437
|
* Issue the DB queries: optional `--tag` allow-list narrowing, the
|
|
@@ -18332,7 +18439,7 @@ var ListCommand = class extends SmCommand {
|
|
|
18332
18439
|
* out so `run()` reads as a thin orchestrator.
|
|
18333
18440
|
*/
|
|
18334
18441
|
async #runQuery(adapter, flags) {
|
|
18335
|
-
const tagAllowList = await this.#resolveTagAllowList(adapter
|
|
18442
|
+
const tagAllowList = await this.#resolveTagAllowList(adapter);
|
|
18336
18443
|
if (tagAllowList === "no-match") return this.#renderEmpty();
|
|
18337
18444
|
const filter = this.#buildFindNodesFilter(flags);
|
|
18338
18445
|
const allMatchingNodes = await adapter.scans.findNodes(filter);
|
|
@@ -18348,16 +18455,15 @@ var ListCommand = class extends SmCommand {
|
|
|
18348
18455
|
return ExitCode.Ok;
|
|
18349
18456
|
}
|
|
18350
18457
|
/**
|
|
18351
|
-
* Resolve `--tag`
|
|
18352
|
-
* path allow-list. Returns:
|
|
18458
|
+
* Resolve `--tag` into a path allow-list. Returns:
|
|
18353
18459
|
* - `null` when `--tag` was not supplied (no narrowing).
|
|
18354
18460
|
* - `'no-match'` when the tag matched zero nodes (caller renders
|
|
18355
18461
|
* the empty surface and exits).
|
|
18356
18462
|
* - a Set of paths otherwise.
|
|
18357
18463
|
*/
|
|
18358
|
-
async #resolveTagAllowList(adapter
|
|
18464
|
+
async #resolveTagAllowList(adapter) {
|
|
18359
18465
|
if (this.tag === void 0) return null;
|
|
18360
|
-
const matchingPaths = await adapter.tags.findNodes(this.tag
|
|
18466
|
+
const matchingPaths = await adapter.tags.findNodes(this.tag);
|
|
18361
18467
|
if (matchingPaths.length === 0) return "no-match";
|
|
18362
18468
|
return new Set(matchingPaths);
|
|
18363
18469
|
}
|
|
@@ -20447,7 +20553,7 @@ function resolveBareToggle(id, catalogue) {
|
|
|
20447
20553
|
}
|
|
20448
20554
|
|
|
20449
20555
|
// cli/commands/plugins/create.ts
|
|
20450
|
-
import { existsSync as
|
|
20556
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync5, writeFileSync } from "fs";
|
|
20451
20557
|
import { join as join18, resolve as resolve33 } from "path";
|
|
20452
20558
|
import { Command as Command26, Option as Option25 } from "clipanion";
|
|
20453
20559
|
var PluginsCreateCommand = class extends SmCommand {
|
|
@@ -20476,7 +20582,7 @@ var PluginsCreateCommand = class extends SmCommand {
|
|
|
20476
20582
|
const ctx = defaultRuntimeContext();
|
|
20477
20583
|
const baseDir = defaultProjectPluginsDir(ctx);
|
|
20478
20584
|
const targetDir = this.at ? resolve33(this.at) : join18(baseDir, this.pluginId);
|
|
20479
|
-
if (
|
|
20585
|
+
if (existsSync24(targetDir) && !this.force) {
|
|
20480
20586
|
this.printer.error(
|
|
20481
20587
|
tx(PLUGINS_TEXTS.createRefuseOverwrite, {
|
|
20482
20588
|
glyph: errGlyph,
|
|
@@ -21202,6 +21308,12 @@ var RUNTIME_TEXTS = {
|
|
|
21202
21308
|
|
|
21203
21309
|
// core/watcher/runtime.ts
|
|
21204
21310
|
var DEFAULT_RUN_INITIAL_BATCH = true;
|
|
21311
|
+
async function rebuildWatcherDbOnDrift(dbPath, events) {
|
|
21312
|
+
const drift = await maybeResetOnDrift(dbPath, { currentVersion: VERSION, assumeYes: true });
|
|
21313
|
+
if (drift.kind === "reset") {
|
|
21314
|
+
events.onDriftReset?.({ dbVersion: drift.dbVersion, currentVersion: drift.currentVersion });
|
|
21315
|
+
}
|
|
21316
|
+
}
|
|
21205
21317
|
function createWatcherRuntime(opts) {
|
|
21206
21318
|
const events = opts.events ?? {};
|
|
21207
21319
|
const cwd = opts.runtimeContext.cwd;
|
|
@@ -21245,6 +21357,7 @@ function createWatcherRuntime(opts) {
|
|
|
21245
21357
|
};
|
|
21246
21358
|
let handleBatch = null;
|
|
21247
21359
|
const start = async () => {
|
|
21360
|
+
await rebuildWatcherDbOnDrift(opts.dbPath, events);
|
|
21248
21361
|
cfg = loadEffectiveConfig();
|
|
21249
21362
|
ignoreFilter = composeIgnoreFilter(cfg, readIgnoreFileText(cwd));
|
|
21250
21363
|
applyConfigDerivedState(cfg);
|
|
@@ -21600,6 +21713,16 @@ async function runWatchLoop(opts) {
|
|
|
21600
21713
|
printer.warn(`${message}
|
|
21601
21714
|
`);
|
|
21602
21715
|
},
|
|
21716
|
+
onDriftReset: (info) => {
|
|
21717
|
+
context.stderr.write(
|
|
21718
|
+
tx(DB_DRIFT_TEXTS.driftReset, {
|
|
21719
|
+
glyph: stderrAnsi.yellow("\u26A0"),
|
|
21720
|
+
dbVersion: info.dbVersion,
|
|
21721
|
+
currentVersion: info.currentVersion,
|
|
21722
|
+
hint: stderrAnsi.dim(DB_DRIFT_TEXTS.driftResetHint)
|
|
21723
|
+
})
|
|
21724
|
+
);
|
|
21725
|
+
},
|
|
21603
21726
|
onConfigLoaded: ({ debounceMs }) => {
|
|
21604
21727
|
if (opts.json) return;
|
|
21605
21728
|
context.stderr.write(
|
|
@@ -21821,7 +21944,7 @@ var ScanCommand = class extends SmCommand {
|
|
|
21821
21944
|
description: "Long-running mode: watch the roots and trigger an incremental scan after each debounced batch of filesystem events. Alias of `sm watch`."
|
|
21822
21945
|
});
|
|
21823
21946
|
yes = Option29.Boolean("--yes", false, {
|
|
21824
|
-
description: "Non-interactive mode
|
|
21947
|
+
description: "Non-interactive mode. For ambiguous activeProvider auto-detect, multiple provider markers (.claude/, .codex/, AGENTS.md, .cursor/) under the scan tree exit non-zero instead of prompting; set the lens manually via `sm config set activeProvider <id>` and re-run. Also auto-confirms the pre-1.0 schema-drift rebuild (when the DB was written by a different skill-map major.minor it is deleted and regenerated) instead of prompting."
|
|
21825
21948
|
});
|
|
21826
21949
|
maxNodes = Option29.String("--max-nodes", {
|
|
21827
21950
|
required: false,
|
|
@@ -22355,7 +22478,7 @@ function renderDeltaIssues(issues) {
|
|
|
22355
22478
|
|
|
22356
22479
|
// cli/commands/serve.ts
|
|
22357
22480
|
import { spawn as spawn2 } from "child_process";
|
|
22358
|
-
import { existsSync as
|
|
22481
|
+
import { existsSync as existsSync30 } from "fs";
|
|
22359
22482
|
import { Command as Command33, Option as Option31 } from "clipanion";
|
|
22360
22483
|
|
|
22361
22484
|
// kernel/util/dev-mode.ts
|
|
@@ -22510,6 +22633,11 @@ var SERVER_TEXTS = {
|
|
|
22510
22633
|
// watcher loop continues, a transient FS error must not kill the
|
|
22511
22634
|
// broadcaster.
|
|
22512
22635
|
watcherBatchFailed: "skill-map server: watcher batch failed ({{message}}).\n",
|
|
22636
|
+
// Logged once when the pre-1.0 schema-drift check rebuilt the DB on
|
|
22637
|
+
// watcher boot (the on-disk cache was written by a different
|
|
22638
|
+
// major.minor). The scan that follows repopulates it; .sm sidecars
|
|
22639
|
+
// are untouched. See spec/db-schema.md §Schema drift (pre-1.0).
|
|
22640
|
+
watcherDriftReset: "skill-map server: local cache rebuilt (was {{dbVersion}}, now on {{currentVersion}}); .sm sidecars untouched.\n",
|
|
22513
22641
|
// chokidar surfaced an error. The watcher stays open per IFsWatcher's
|
|
22514
22642
|
// contract; the BFF also broadcasts a `watcher.error` advisory so the
|
|
22515
22643
|
// SPA can surface it in the live event log.
|
|
@@ -23090,7 +23218,7 @@ function contentTypeFor(format) {
|
|
|
23090
23218
|
}
|
|
23091
23219
|
|
|
23092
23220
|
// server/health.ts
|
|
23093
|
-
import { existsSync as
|
|
23221
|
+
import { existsSync as existsSync25 } from "fs";
|
|
23094
23222
|
var FALLBACK_SCHEMA_VERSION = "1";
|
|
23095
23223
|
function buildHealth(deps) {
|
|
23096
23224
|
const dev = isDevBuild();
|
|
@@ -23099,7 +23227,7 @@ function buildHealth(deps) {
|
|
|
23099
23227
|
schemaVersion: FALLBACK_SCHEMA_VERSION,
|
|
23100
23228
|
specVersion: deps.specVersion,
|
|
23101
23229
|
implVersion: VERSION,
|
|
23102
|
-
db:
|
|
23230
|
+
db: existsSync25(deps.dbPath) ? "present" : "missing",
|
|
23103
23231
|
cwd: deps.cwd,
|
|
23104
23232
|
dbPath: deps.dbPath,
|
|
23105
23233
|
// Only emit when truthy so a published install keeps the wire
|
|
@@ -23350,7 +23478,7 @@ function registerNodesRoutes(app, deps) {
|
|
|
23350
23478
|
bundle: null,
|
|
23351
23479
|
isFavorite: false,
|
|
23352
23480
|
contributions: [],
|
|
23353
|
-
tags:
|
|
23481
|
+
tags: []
|
|
23354
23482
|
};
|
|
23355
23483
|
}
|
|
23356
23484
|
const favSet = await adapter.favorites.listPaths();
|
|
@@ -23360,14 +23488,14 @@ function registerNodesRoutes(app, deps) {
|
|
|
23360
23488
|
bundle: b,
|
|
23361
23489
|
isFavorite: favSet.has(b.node.path),
|
|
23362
23490
|
contributions: contributions2,
|
|
23363
|
-
tags:
|
|
23491
|
+
tags: tagRows.map((r) => r.tag)
|
|
23364
23492
|
};
|
|
23365
23493
|
}
|
|
23366
23494
|
);
|
|
23367
23495
|
const bundle = result?.bundle ?? null;
|
|
23368
23496
|
const isFavorite = result?.isFavorite ?? false;
|
|
23369
23497
|
const contributions = result?.contributions ?? [];
|
|
23370
|
-
const tags = result?.tags ??
|
|
23498
|
+
const tags = result?.tags ?? [];
|
|
23371
23499
|
if (!bundle) {
|
|
23372
23500
|
throw new HTTPException6(404, {
|
|
23373
23501
|
message: tx(SERVER_TEXTS.nodeNotFound, { path: nodePath })
|
|
@@ -23421,7 +23549,7 @@ function registerNodesRoutes(app, deps) {
|
|
|
23421
23549
|
const contribByPath = contributionsOmitted ? /* @__PURE__ */ new Map() : await groupContributionsByPath(
|
|
23422
23550
|
await adapter.contributions.listForPaths(pagePaths)
|
|
23423
23551
|
);
|
|
23424
|
-
const tagByPath =
|
|
23552
|
+
const tagByPath = groupTagsByPath(
|
|
23425
23553
|
await adapter.tags.listForPaths(pagePaths)
|
|
23426
23554
|
);
|
|
23427
23555
|
return { contributionsByPath: contribByPath, tagsByPath: tagByPath };
|
|
@@ -23434,7 +23562,7 @@ function registerNodesRoutes(app, deps) {
|
|
|
23434
23562
|
...n,
|
|
23435
23563
|
isFavorite: favSet.has(n.path),
|
|
23436
23564
|
contributions: contributionsByPath.get(n.path) ?? [],
|
|
23437
|
-
tags: tagsByPath.get(n.path) ??
|
|
23565
|
+
tags: tagsByPath.get(n.path) ?? []
|
|
23438
23566
|
}));
|
|
23439
23567
|
return c.json(
|
|
23440
23568
|
buildListEnvelope({
|
|
@@ -23457,24 +23585,15 @@ function registerNodesRoutes(app, deps) {
|
|
|
23457
23585
|
function parseIncludes(raw) {
|
|
23458
23586
|
return new Set(parseCsv(raw));
|
|
23459
23587
|
}
|
|
23460
|
-
function
|
|
23461
|
-
const byAuthor = /* @__PURE__ */ new Set();
|
|
23462
|
-
const byUser = /* @__PURE__ */ new Set();
|
|
23463
|
-
for (const r of rows) (r.source === "author" ? byAuthor : byUser).add(r.tag);
|
|
23464
|
-
return {
|
|
23465
|
-
byAuthor: [...byAuthor].sort(),
|
|
23466
|
-
byUser: [...byUser].sort()
|
|
23467
|
-
};
|
|
23468
|
-
}
|
|
23469
|
-
async function groupTagsByPath(rows) {
|
|
23588
|
+
function groupTagsByPath(rows) {
|
|
23470
23589
|
const buckets = /* @__PURE__ */ new Map();
|
|
23471
23590
|
for (const r of rows) {
|
|
23472
|
-
const
|
|
23473
|
-
if (
|
|
23474
|
-
else buckets.set(r.nodePath,
|
|
23591
|
+
const set = buckets.get(r.nodePath);
|
|
23592
|
+
if (set) set.add(r.tag);
|
|
23593
|
+
else buckets.set(r.nodePath, /* @__PURE__ */ new Set([r.tag]));
|
|
23475
23594
|
}
|
|
23476
23595
|
const out = /* @__PURE__ */ new Map();
|
|
23477
|
-
for (const [path,
|
|
23596
|
+
for (const [path, set] of buckets) out.set(path, [...set].sort());
|
|
23478
23597
|
return out;
|
|
23479
23598
|
}
|
|
23480
23599
|
async function groupContributionsByPath(rows) {
|
|
@@ -23981,12 +24100,12 @@ var parsePatchBody2 = makeBodyValidator(PATCH_BODY_SCHEMA, {
|
|
|
23981
24100
|
import { HTTPException as HTTPException10 } from "hono/http-exception";
|
|
23982
24101
|
|
|
23983
24102
|
// server/util/skillmapignore-io.ts
|
|
23984
|
-
import { existsSync as
|
|
24103
|
+
import { existsSync as existsSync26, readFileSync as readFileSync17, writeFileSync as writeFileSync2 } from "fs";
|
|
23985
24104
|
import { resolve as resolve35 } from "path";
|
|
23986
24105
|
var IGNORE_FILENAME2 = ".skillmapignore";
|
|
23987
24106
|
function readPatterns(cwd) {
|
|
23988
24107
|
const path = resolve35(cwd, IGNORE_FILENAME2);
|
|
23989
|
-
if (!
|
|
24108
|
+
if (!existsSync26(path)) return [];
|
|
23990
24109
|
let raw;
|
|
23991
24110
|
try {
|
|
23992
24111
|
raw = readFileSync17(path, "utf8");
|
|
@@ -23997,7 +24116,7 @@ function readPatterns(cwd) {
|
|
|
23997
24116
|
}
|
|
23998
24117
|
function writePatterns(cwd, nextPatterns) {
|
|
23999
24118
|
const path = resolve35(cwd, IGNORE_FILENAME2);
|
|
24000
|
-
const prior =
|
|
24119
|
+
const prior = existsSync26(path) ? safeRead(path) : "";
|
|
24001
24120
|
const content = buildContent(prior, nextPatterns);
|
|
24002
24121
|
writeFileSync2(path, content, "utf8");
|
|
24003
24122
|
}
|
|
@@ -24347,7 +24466,7 @@ var parsePatchBody4 = makeBodyValidator(PATCH_BODY_SCHEMA3, {
|
|
|
24347
24466
|
});
|
|
24348
24467
|
|
|
24349
24468
|
// server/routes/active-provider.ts
|
|
24350
|
-
import { existsSync as
|
|
24469
|
+
import { existsSync as existsSync27 } from "fs";
|
|
24351
24470
|
import { HTTPException as HTTPException12 } from "hono/http-exception";
|
|
24352
24471
|
function registerActiveProviderRoute(app, deps) {
|
|
24353
24472
|
app.get("/api/active-provider", (c) => {
|
|
@@ -24380,7 +24499,7 @@ function applyLensSwitch(deps, newValue) {
|
|
|
24380
24499
|
});
|
|
24381
24500
|
}
|
|
24382
24501
|
const dbPath = resolveDbPath({ db: void 0, cwd });
|
|
24383
|
-
if (!
|
|
24502
|
+
if (!existsSync27(dbPath)) return { dropped: null };
|
|
24384
24503
|
const dropResult = dropScanZone(dbPath);
|
|
24385
24504
|
return {
|
|
24386
24505
|
dropped: {
|
|
@@ -24501,6 +24620,14 @@ function createWatcherService(opts) {
|
|
|
24501
24620
|
onPluginWarning: (message) => {
|
|
24502
24621
|
log.warn(sanitizeForTerminal(message));
|
|
24503
24622
|
},
|
|
24623
|
+
onDriftReset: (info) => {
|
|
24624
|
+
log.warn(
|
|
24625
|
+
tx(SERVER_TEXTS.watcherDriftReset, {
|
|
24626
|
+
dbVersion: info.dbVersion,
|
|
24627
|
+
currentVersion: info.currentVersion
|
|
24628
|
+
})
|
|
24629
|
+
);
|
|
24630
|
+
},
|
|
24504
24631
|
onReady: (info) => {
|
|
24505
24632
|
opts.broadcaster.broadcast(
|
|
24506
24633
|
buildWatcherStartedEvent({ roots: info.roots, debounceMs: info.debounceMs })
|
|
@@ -24643,13 +24770,8 @@ async function loadPersistedScan(deps) {
|
|
|
24643
24770
|
if (list) list.push(r);
|
|
24644
24771
|
else byPath3.set(r.nodePath, [r]);
|
|
24645
24772
|
}
|
|
24646
|
-
const
|
|
24647
|
-
|
|
24648
|
-
const list = tagBuckets.get(r.nodePath);
|
|
24649
|
-
if (list) list.push({ tag: r.tag, source: r.source });
|
|
24650
|
-
else tagBuckets.set(r.nodePath, [{ tag: r.tag, source: r.source }]);
|
|
24651
|
-
}
|
|
24652
|
-
return { loaded, favSet, contribByPath: byPath3, tagBuckets };
|
|
24773
|
+
const tagsByPath = groupTagsByPath2(tagRows);
|
|
24774
|
+
return { loaded, favSet, contribByPath: byPath3, tagsByPath };
|
|
24653
24775
|
}
|
|
24654
24776
|
);
|
|
24655
24777
|
if (opened === null) {
|
|
@@ -24661,18 +24783,20 @@ async function loadPersistedScan(deps) {
|
|
|
24661
24783
|
...n,
|
|
24662
24784
|
isFavorite: opened.favSet.has(n.path),
|
|
24663
24785
|
contributions: opened.contribByPath.get(n.path) ?? [],
|
|
24664
|
-
tags:
|
|
24786
|
+
tags: opened.tagsByPath.get(n.path) ?? []
|
|
24665
24787
|
}))
|
|
24666
24788
|
};
|
|
24667
24789
|
}
|
|
24668
|
-
function
|
|
24669
|
-
const
|
|
24670
|
-
const
|
|
24671
|
-
|
|
24672
|
-
|
|
24673
|
-
|
|
24674
|
-
|
|
24675
|
-
|
|
24790
|
+
function groupTagsByPath2(rows) {
|
|
24791
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
24792
|
+
for (const r of rows) {
|
|
24793
|
+
const set = buckets.get(r.nodePath);
|
|
24794
|
+
if (set) set.add(r.tag);
|
|
24795
|
+
else buckets.set(r.nodePath, /* @__PURE__ */ new Set([r.tag]));
|
|
24796
|
+
}
|
|
24797
|
+
const out = /* @__PURE__ */ new Map();
|
|
24798
|
+
for (const [path, set] of buckets) out.set(path, [...set].sort());
|
|
24799
|
+
return out;
|
|
24676
24800
|
}
|
|
24677
24801
|
async function runFreshScan(deps) {
|
|
24678
24802
|
if (deps.options.noBuiltIns || deps.options.noPlugins) {
|
|
@@ -24910,7 +25034,7 @@ function registerUpdateStatusRoute(app, deps) {
|
|
|
24910
25034
|
}
|
|
24911
25035
|
|
|
24912
25036
|
// server/static.ts
|
|
24913
|
-
import { existsSync as
|
|
25037
|
+
import { existsSync as existsSync28 } from "fs";
|
|
24914
25038
|
import { readFile as readFile6 } from "fs/promises";
|
|
24915
25039
|
import { extname, join as join19 } from "path";
|
|
24916
25040
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
@@ -24965,7 +25089,7 @@ function createSpaFallback(opts) {
|
|
|
24965
25089
|
if (c.req.method !== "GET" && c.req.method !== "HEAD") return c.notFound();
|
|
24966
25090
|
if (opts.uiDist === null) return htmlResponse(c, placeholder);
|
|
24967
25091
|
const indexPath = join19(opts.uiDist, INDEX_HTML);
|
|
24968
|
-
if (!
|
|
25092
|
+
if (!existsSync28(indexPath)) return htmlResponse(c, placeholder);
|
|
24969
25093
|
return fileResponse(c, indexPath);
|
|
24970
25094
|
};
|
|
24971
25095
|
}
|
|
@@ -25574,7 +25698,7 @@ function validateNoUi(noUi, uiDist) {
|
|
|
25574
25698
|
}
|
|
25575
25699
|
|
|
25576
25700
|
// server/paths.ts
|
|
25577
|
-
import { existsSync as
|
|
25701
|
+
import { existsSync as existsSync29, statSync as statSync10 } from "fs";
|
|
25578
25702
|
import { dirname as dirname18, isAbsolute as isAbsolute11, join as join20, resolve as resolve37 } from "path";
|
|
25579
25703
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
25580
25704
|
var DEFAULT_UI_REL = join20("ui", "dist", "ui", "browser");
|
|
@@ -25589,10 +25713,10 @@ function resolveExplicitUiDist(ctx, raw) {
|
|
|
25589
25713
|
return isAbsolute11(raw) ? raw : resolve37(ctx.cwd, raw);
|
|
25590
25714
|
}
|
|
25591
25715
|
function isUiBundleDir(path) {
|
|
25592
|
-
if (!
|
|
25716
|
+
if (!existsSync29(path)) return false;
|
|
25593
25717
|
try {
|
|
25594
25718
|
if (!statSync10(path).isDirectory()) return false;
|
|
25595
|
-
return
|
|
25719
|
+
return existsSync29(join20(path, INDEX_HTML2));
|
|
25596
25720
|
} catch {
|
|
25597
25721
|
return false;
|
|
25598
25722
|
}
|
|
@@ -26147,7 +26271,7 @@ var ServeCommand = class extends SmCommand {
|
|
|
26147
26271
|
return ExitCode.Error;
|
|
26148
26272
|
}
|
|
26149
26273
|
const dbPath = resolveDbPath({ db: this.db, ...runtimeCtx });
|
|
26150
|
-
if (this.db !== void 0 && !
|
|
26274
|
+
if (this.db !== void 0 && !existsSync30(dbPath)) {
|
|
26151
26275
|
this.printer.info(
|
|
26152
26276
|
tx(SERVE_TEXTS.dbNotFound, {
|
|
26153
26277
|
glyph: errGlyph,
|
|
@@ -27412,7 +27536,7 @@ var STUB_COMMANDS = [
|
|
|
27412
27536
|
];
|
|
27413
27537
|
|
|
27414
27538
|
// cli/commands/tutorial.ts
|
|
27415
|
-
import { cpSync as cpSync2, existsSync as
|
|
27539
|
+
import { cpSync as cpSync2, existsSync as existsSync31, mkdirSync as mkdirSync6, rmSync as rmSync2, statSync as statSync11 } from "fs";
|
|
27416
27540
|
import { dirname as dirname19, join as join21, resolve as resolve39 } from "path";
|
|
27417
27541
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
27418
27542
|
import { Command as Command37, Option as Option35 } from "clipanion";
|
|
@@ -27511,7 +27635,7 @@ var TutorialCommand = class extends SmCommand {
|
|
|
27511
27635
|
const spec = VARIANT_SPECS[variant];
|
|
27512
27636
|
const targetDir = join21(ctx.cwd, ".claude", "skills", spec.slug);
|
|
27513
27637
|
const targetDisplay = `.claude/skills/${spec.slug}/`;
|
|
27514
|
-
if (
|
|
27638
|
+
if (existsSync31(targetDir) && !this.force) {
|
|
27515
27639
|
this.printer.error(
|
|
27516
27640
|
tx(TUTORIAL_TEXTS.alreadyExists, {
|
|
27517
27641
|
glyph: errGlyph,
|
|
@@ -27594,7 +27718,7 @@ function resolveSkillSourceDir(variant) {
|
|
|
27594
27718
|
resolve39(here, "../cli/tutorial", spec.slug)
|
|
27595
27719
|
];
|
|
27596
27720
|
for (const candidate of candidates) {
|
|
27597
|
-
if (
|
|
27721
|
+
if (existsSync31(candidate) && statSync11(candidate).isDirectory()) {
|
|
27598
27722
|
cachedSourceDirs.set(variant, candidate);
|
|
27599
27723
|
return candidate;
|
|
27600
27724
|
}
|
|
@@ -27779,7 +27903,7 @@ function resolveBareInvocation(rawArgs) {
|
|
|
27779
27903
|
if (first !== void 0 && first.startsWith("-") && !passthrough.has(first)) {
|
|
27780
27904
|
const isSingleDashLong = !first.startsWith("--") && first.length > 2;
|
|
27781
27905
|
if (isSingleDashLong) return null;
|
|
27782
|
-
if (
|
|
27906
|
+
if (existsSync32(defaultProjectDbPath(defaultRuntimeContext()))) {
|
|
27783
27907
|
return ["serve", ...rawArgs];
|
|
27784
27908
|
}
|
|
27785
27909
|
return resolveBareDefault();
|
|
@@ -27788,7 +27912,7 @@ function resolveBareInvocation(rawArgs) {
|
|
|
27788
27912
|
}
|
|
27789
27913
|
function resolveBareDefault() {
|
|
27790
27914
|
const ctx = defaultRuntimeContext();
|
|
27791
|
-
if (
|
|
27915
|
+
if (existsSync32(defaultProjectDbPath(ctx))) {
|
|
27792
27916
|
return ["serve"];
|
|
27793
27917
|
}
|
|
27794
27918
|
const stderr = process.stderr;
|