@skill-map/cli 0.59.0 → 0.60.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/tutorial/sm-tutorial/SKILL.md +12 -5
- package/dist/cli/tutorial/sm-tutorial/references/fixtures.md +15 -4
- package/dist/cli/tutorial/sm-tutorial/references/part-cli.md +3 -3
- package/dist/cli/tutorial/sm-tutorial/references/part-connect-harness.md +19 -15
- package/dist/cli/tutorial/sm-tutorial/references/part-daily-loop.md +4 -2
- package/dist/cli/tutorial/sm-tutorial/references/part-fundamentals.md +59 -44
- package/dist/cli/tutorial/sm-tutorial/references/part-project-kickoff.md +18 -0
- package/dist/cli.js +160 -76
- package/dist/index.js +3 -3
- package/dist/kernel/index.d.ts +20 -0
- package/dist/kernel/index.js +3 -3
- package/dist/ui/chunk-4N3NRZEH.js +809 -0
- package/dist/ui/chunk-5SSKJ7AM.js +1 -0
- package/dist/ui/{chunk-WB7FKIBP.js → chunk-7VUEZZFJ.js} +1 -1
- package/dist/ui/{chunk-P2DAPRK7.js → chunk-7X3DZNG4.js} +1 -1
- package/dist/ui/chunk-AKKFFP7Y.js +1 -0
- package/dist/ui/chunk-COXOWJFC.js +3 -0
- package/dist/ui/{chunk-JA4Z74I3.js → chunk-FRUHVCND.js} +1 -1
- package/dist/ui/chunk-GDZRZU57.js +1843 -0
- package/dist/ui/{chunk-K2MAVAHG.js → chunk-GKQA75EF.js} +1 -1
- package/dist/ui/chunk-HQ6M2HXK.js +369 -0
- package/dist/ui/chunk-JRVAI7GI.js +2 -0
- package/dist/ui/chunk-JTCIY3SL.js +742 -0
- package/dist/ui/chunk-MBBJJEUX.js +917 -0
- package/dist/ui/{chunk-LCOYSPKE.js → chunk-MGWGV4VD.js} +1 -1
- package/dist/ui/chunk-N6MUHKWR.js +105 -0
- package/dist/ui/chunk-OGXBHDY4.js +1 -0
- package/dist/ui/{chunk-KHARMPTZ.js → chunk-OVVTCPBJ.js} +1 -1
- package/dist/ui/{chunk-UBQUCSQ4.js → chunk-Q4PXVDJA.js} +1 -1
- package/dist/ui/chunk-ZYPXVXYF.js +4 -0
- package/dist/ui/index.html +1 -1
- package/dist/ui/main-5MKN73KQ.js +4 -0
- package/package.json +2 -2
- package/dist/ui/chunk-BCEJCDZB.js +0 -3
- package/dist/ui/chunk-DPLNM4UD.js +0 -2
- package/dist/ui/chunk-G3ZVF4TM.js +0 -1
- package/dist/ui/chunk-H6O2DYVT.js +0 -1110
- package/dist/ui/chunk-KJZQIUZA.js +0 -917
- package/dist/ui/chunk-Q2A6FWC7.js +0 -4
- package/dist/ui/chunk-QVNZN5F7.js +0 -1843
- package/dist/ui/chunk-SXXFDP6V.js +0 -1
- package/dist/ui/chunk-YHJL5LP3.js +0 -913
- package/dist/ui/main-PHRAKC4A.js +0 -4
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// cli/entry.ts
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7e14428f-63d1-5e95-8756-98cea6d3c76e")}catch(e){}}();
|
|
4
4
|
import { existsSync as existsSync33 } from "fs";
|
|
5
5
|
import { Builtins, Cli as Cli2 } from "clipanion";
|
|
6
6
|
|
|
@@ -250,7 +250,7 @@ function bucketByKind(kind, instance, bag) {
|
|
|
250
250
|
// package.json
|
|
251
251
|
var package_default = {
|
|
252
252
|
name: "@skill-map/cli",
|
|
253
|
-
version: "0.
|
|
253
|
+
version: "0.60.0",
|
|
254
254
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
255
255
|
license: "MIT",
|
|
256
256
|
type: "module",
|
|
@@ -2657,14 +2657,14 @@ var experimental = {
|
|
|
2657
2657
|
slot: "card.footer.right",
|
|
2658
2658
|
icon: "fa-solid fa-flask",
|
|
2659
2659
|
label: "experimental",
|
|
2660
|
-
emitWhenEmpty:
|
|
2660
|
+
emitWhenEmpty: true,
|
|
2661
2661
|
priority: 10
|
|
2662
2662
|
};
|
|
2663
2663
|
var deprecated = {
|
|
2664
2664
|
slot: "card.footer.right",
|
|
2665
2665
|
icon: "pi-ban",
|
|
2666
2666
|
label: "deprecated",
|
|
2667
|
-
emitWhenEmpty:
|
|
2667
|
+
emitWhenEmpty: true,
|
|
2668
2668
|
priority: 10
|
|
2669
2669
|
};
|
|
2670
2670
|
var nodeStabilityAnalyzer = {
|
|
@@ -3665,6 +3665,10 @@ var nodeBumpAction = {
|
|
|
3665
3665
|
// the drift analyzer that motivates it.
|
|
3666
3666
|
stability: "experimental",
|
|
3667
3667
|
mode: "deterministic",
|
|
3668
|
+
// Declares the sidecar-write capability: `invoke()` returns a
|
|
3669
|
+
// `{ kind: 'sidecar' }` write, so consumers (the `allowSidecarWriters`
|
|
3670
|
+
// policy) can gate this action without invoking it.
|
|
3671
|
+
writes: ["sidecar"],
|
|
3668
3672
|
ui: { bumpButton },
|
|
3669
3673
|
project(ctx) {
|
|
3670
3674
|
for (const node of ctx.nodes) {
|
|
@@ -3765,6 +3769,10 @@ var nodeSetStabilityAction = {
|
|
|
3765
3769
|
kind: "action",
|
|
3766
3770
|
description: "Sets the lifecycle stage of the current node (writes `stability` to the sidecar).",
|
|
3767
3771
|
mode: "deterministic",
|
|
3772
|
+
// Declares the sidecar-write capability: `invoke()` returns a
|
|
3773
|
+
// `{ kind: 'sidecar' }` write, so the `allowSidecarWriters` policy can
|
|
3774
|
+
// gate this action without invoking it.
|
|
3775
|
+
writes: ["sidecar"],
|
|
3768
3776
|
ui: { setStabilityButton },
|
|
3769
3777
|
project(ctx) {
|
|
3770
3778
|
for (const node of ctx.nodes) {
|
|
@@ -3827,33 +3835,18 @@ function invokeSetStability(input, ctx) {
|
|
|
3827
3835
|
return { report, writes: [write] };
|
|
3828
3836
|
}
|
|
3829
3837
|
|
|
3830
|
-
// plugins/core/actions/node-set-tags/text.ts
|
|
3831
|
-
var TAGS_TEXTS = {
|
|
3832
|
-
/** Label of the inspector action button that edits the node's tags. */
|
|
3833
|
-
editLabel: "Edit tags",
|
|
3834
|
-
/** Prompt label for the string-list tags input. */
|
|
3835
|
-
promptLabel: "Tags"
|
|
3836
|
-
};
|
|
3837
|
-
|
|
3838
3838
|
// plugins/core/actions/node-set-tags/index.ts
|
|
3839
3839
|
var ID27 = "node-set-tags";
|
|
3840
|
-
var setTagsButton = {
|
|
3841
|
-
slot: "inspector.action.button",
|
|
3842
|
-
priority: 15
|
|
3843
|
-
};
|
|
3844
3840
|
var nodeSetTagsAction = {
|
|
3845
3841
|
id: ID27,
|
|
3846
3842
|
pluginId: CORE_PLUGIN_ID,
|
|
3847
3843
|
kind: "action",
|
|
3848
3844
|
description: "Sets the taxonomy tags of the current node (writes `tags` to the sidecar; whole-array replace).",
|
|
3849
3845
|
mode: "deterministic",
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
emitSetTagsButton(ctx, node);
|
|
3855
|
-
}
|
|
3856
|
-
},
|
|
3846
|
+
// Declares the sidecar-write capability: `invoke()` returns a
|
|
3847
|
+
// `{ kind: 'sidecar' }` write, so the `allowSidecarWriters` policy can
|
|
3848
|
+
// gate this action without invoking it.
|
|
3849
|
+
writes: ["sidecar"],
|
|
3857
3850
|
// The runtime contract uses generic <TInput, TReport>; this narrows
|
|
3858
3851
|
// both. The cast is the standard pattern for built-ins that want
|
|
3859
3852
|
// typed local I/O while staying compatible with the open generic.
|
|
@@ -3862,29 +3855,21 @@ var nodeSetTagsAction = {
|
|
|
3862
3855
|
return invokeSetTags(input, ctx);
|
|
3863
3856
|
}
|
|
3864
3857
|
};
|
|
3865
|
-
function
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
});
|
|
3878
|
-
}
|
|
3879
|
-
function currentTags(node) {
|
|
3880
|
-
const ann = node.sidecar?.annotations;
|
|
3881
|
-
if (!ann || typeof ann !== "object" || Array.isArray(ann)) return [];
|
|
3882
|
-
const value = ann["tags"];
|
|
3883
|
-
if (!Array.isArray(value)) return [];
|
|
3884
|
-
return value.filter((t) => typeof t === "string");
|
|
3858
|
+
function sanitizeTags(raw) {
|
|
3859
|
+
if (!Array.isArray(raw)) return [];
|
|
3860
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3861
|
+
const out = [];
|
|
3862
|
+
for (const entry of raw) {
|
|
3863
|
+
if (typeof entry !== "string") continue;
|
|
3864
|
+
const tag = entry.trim();
|
|
3865
|
+
if (tag.length === 0 || seen.has(tag)) continue;
|
|
3866
|
+
seen.add(tag);
|
|
3867
|
+
out.push(tag);
|
|
3868
|
+
}
|
|
3869
|
+
return out;
|
|
3885
3870
|
}
|
|
3886
3871
|
function invokeSetTags(input, ctx) {
|
|
3887
|
-
const tags =
|
|
3872
|
+
const tags = sanitizeTags(input.tags);
|
|
3888
3873
|
const timestamp = ctx.now().toISOString();
|
|
3889
3874
|
const write = {
|
|
3890
3875
|
kind: "sidecar",
|
|
@@ -5307,6 +5292,7 @@ var CONFIG_LOADER_TEXTS = {
|
|
|
5307
5292
|
var defaults_default = {
|
|
5308
5293
|
schemaVersion: 1,
|
|
5309
5294
|
allowEditSmFiles: false,
|
|
5295
|
+
allowSidecarWriters: true,
|
|
5310
5296
|
tokenizer: "cl100k_base",
|
|
5311
5297
|
roots: [],
|
|
5312
5298
|
ignore: [],
|
|
@@ -5729,7 +5715,27 @@ var EConsentRequiredError = class extends Error {
|
|
|
5729
5715
|
this.hintTarget = init.hintTarget;
|
|
5730
5716
|
}
|
|
5731
5717
|
};
|
|
5718
|
+
var ESidecarWritersForbiddenError = class extends Error {
|
|
5719
|
+
key;
|
|
5720
|
+
constructor(init) {
|
|
5721
|
+
super(
|
|
5722
|
+
`Sidecar-writing extensions are disabled in this project ('${init.key}' is false in .skill-map/settings.json). This is a team-level project policy and cannot be overridden.`
|
|
5723
|
+
);
|
|
5724
|
+
this.name = "ESidecarWritersForbiddenError";
|
|
5725
|
+
this.key = init.key;
|
|
5726
|
+
}
|
|
5727
|
+
};
|
|
5728
|
+
function assertSidecarWritersAllowed(cwd) {
|
|
5729
|
+
const allowed = readConfigValue("allowSidecarWriters", {
|
|
5730
|
+
cwd,
|
|
5731
|
+
default: true
|
|
5732
|
+
});
|
|
5733
|
+
if (allowed === false) {
|
|
5734
|
+
throw new ESidecarWritersForbiddenError({ key: "allowSidecarWriters" });
|
|
5735
|
+
}
|
|
5736
|
+
}
|
|
5732
5737
|
function ensureSidecarWritesAllowed(opts) {
|
|
5738
|
+
assertSidecarWritersAllowed(opts.cwd);
|
|
5733
5739
|
const allowed = readConfigValue("allowEditSmFiles", {
|
|
5734
5740
|
cwd: opts.cwd,
|
|
5735
5741
|
default: false
|
|
@@ -8636,13 +8642,18 @@ function applyIssueFilters(query, filter) {
|
|
|
8636
8642
|
const tokens = filter.analyzerIds;
|
|
8637
8643
|
q = q.where(
|
|
8638
8644
|
({ eb, or }) => or(
|
|
8639
|
-
tokens.flatMap((token) =>
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
|
|
8645
|
+
tokens.flatMap((token) => {
|
|
8646
|
+
const conds = [
|
|
8647
|
+
eb("analyzerId", "=", token),
|
|
8648
|
+
// `'%/' || ?` keeps the LIKE pattern's `%` literal in the
|
|
8649
|
+
// template and binds `token` separately, no interpolation of
|
|
8650
|
+
// user input into the SQL string.
|
|
8651
|
+
eb("analyzerId", "like", `%/${token}`)
|
|
8652
|
+
];
|
|
8653
|
+
const slash = token.indexOf("/");
|
|
8654
|
+
if (slash >= 0) conds.push(eb("analyzerId", "=", token.slice(slash + 1)));
|
|
8655
|
+
return conds;
|
|
8656
|
+
})
|
|
8646
8657
|
)
|
|
8647
8658
|
);
|
|
8648
8659
|
}
|
|
@@ -9120,6 +9131,8 @@ var BumpCommand = class extends SmCommand {
|
|
|
9120
9131
|
const flagError = this.#validateFlagCombo(ansi);
|
|
9121
9132
|
if (flagError !== null) return flagError;
|
|
9122
9133
|
const ctx = defaultRuntimeContext();
|
|
9134
|
+
const policyError = this.#assertWritersAllowed(ansi, ctx.cwd);
|
|
9135
|
+
if (policyError !== null) return policyError;
|
|
9123
9136
|
const dbPath = resolveDbPath({ db: this.db, ...ctx });
|
|
9124
9137
|
const persisted = await tryWithSqlite(
|
|
9125
9138
|
{ databasePath: dbPath, autoBackup: false },
|
|
@@ -9140,6 +9153,22 @@ var BumpCommand = class extends SmCommand {
|
|
|
9140
9153
|
() => this.pending ? this.#runPending(persisted.nodes, ctx.cwd, ansi) : this.#runSingle(persisted.nodes, ctx.cwd, ansi)
|
|
9141
9154
|
);
|
|
9142
9155
|
}
|
|
9156
|
+
/**
|
|
9157
|
+
* Fail-fast guard for the `allowSidecarWriters: false` project policy.
|
|
9158
|
+
* Returns `ExitCode.Error` (after printing the policy message) when
|
|
9159
|
+
* sidecar writers are forbidden, or `null` when writes may proceed.
|
|
9160
|
+
* Re-throws any non-policy error so unexpected failures still surface.
|
|
9161
|
+
*/
|
|
9162
|
+
#assertWritersAllowed(ansi, cwd) {
|
|
9163
|
+
try {
|
|
9164
|
+
assertSidecarWritersAllowed(cwd);
|
|
9165
|
+
return null;
|
|
9166
|
+
} catch (err) {
|
|
9167
|
+
if (!(err instanceof ESidecarWritersForbiddenError)) throw err;
|
|
9168
|
+
this.printer.error(`${ansi.red("\u2715")} ${err.message}`);
|
|
9169
|
+
return ExitCode.Error;
|
|
9170
|
+
}
|
|
9171
|
+
}
|
|
9143
9172
|
/**
|
|
9144
9173
|
* Three argument-validation guards, hoisted out of `run()` so the
|
|
9145
9174
|
* lint complexity cap on `run()` is satisfied without an
|
|
@@ -9547,11 +9576,12 @@ import { Command as Command3, Option as Option3 } from "clipanion";
|
|
|
9547
9576
|
function matchesAnalyzerFilter(analyzerId, filter) {
|
|
9548
9577
|
if (filter.length === 0) return true;
|
|
9549
9578
|
if (filter.includes(analyzerId)) return true;
|
|
9550
|
-
const
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
if (filter.includes(short)) return true;
|
|
9579
|
+
for (const entry of filter) {
|
|
9580
|
+
const slashIdx = entry.indexOf("/");
|
|
9581
|
+
if (slashIdx >= 0 && entry.slice(slashIdx + 1) === analyzerId) return true;
|
|
9554
9582
|
}
|
|
9583
|
+
const argSlashIdx = analyzerId.indexOf("/");
|
|
9584
|
+
if (argSlashIdx >= 0 && filter.includes(analyzerId.slice(argSlashIdx + 1))) return true;
|
|
9555
9585
|
return false;
|
|
9556
9586
|
}
|
|
9557
9587
|
|
|
@@ -11126,6 +11156,7 @@ function filterBuiltInManifests(manifests, resolveEnabled) {
|
|
|
11126
11156
|
function composeScanExtensions(opts) {
|
|
11127
11157
|
const resolveEnabled = opts.resolveEnabled ?? opts.pluginRuntime.resolveEnabled;
|
|
11128
11158
|
const resolveSettings = opts.resolveSettings;
|
|
11159
|
+
const forbidSidecarWriters = opts.forbidSidecarWriters === true;
|
|
11129
11160
|
const providers = [];
|
|
11130
11161
|
const extractors = [];
|
|
11131
11162
|
const analyzers = [];
|
|
@@ -11135,7 +11166,8 @@ function composeScanExtensions(opts) {
|
|
|
11135
11166
|
accumulateBuiltInScanExtensions(
|
|
11136
11167
|
{ providers, extractors, analyzers, hooks, actions },
|
|
11137
11168
|
resolveEnabled,
|
|
11138
|
-
resolveSettings
|
|
11169
|
+
resolveSettings,
|
|
11170
|
+
forbidSidecarWriters
|
|
11139
11171
|
);
|
|
11140
11172
|
}
|
|
11141
11173
|
for (const ext of opts.pluginRuntime.extensions.providers) {
|
|
@@ -11151,7 +11183,9 @@ function composeScanExtensions(opts) {
|
|
|
11151
11183
|
if (isPluginExtensionEnabled(ext, resolveEnabled)) hooks.push(withResolvedSettings(ext, resolveSettings));
|
|
11152
11184
|
}
|
|
11153
11185
|
for (const ext of opts.pluginRuntime.extensions.actions) {
|
|
11154
|
-
if (isPluginExtensionEnabled(ext, resolveEnabled))
|
|
11186
|
+
if (!isPluginExtensionEnabled(ext, resolveEnabled)) continue;
|
|
11187
|
+
if (forbidSidecarWriters && isSidecarWriterAction(ext)) continue;
|
|
11188
|
+
actions.push(ext);
|
|
11155
11189
|
}
|
|
11156
11190
|
const finalProviders = opts.killSwitches?.providers === true ? [] : providers;
|
|
11157
11191
|
const finalExtractors = opts.killSwitches?.extractors === true ? [] : extractors;
|
|
@@ -11171,7 +11205,10 @@ function withResolvedSettings(ext, resolveSettings) {
|
|
|
11171
11205
|
if (!resolveSettings) return ext;
|
|
11172
11206
|
return { ...ext, resolvedSettings: resolveSettings(ext) };
|
|
11173
11207
|
}
|
|
11174
|
-
function
|
|
11208
|
+
function isSidecarWriterAction(ext) {
|
|
11209
|
+
return ext.writes?.includes("sidecar") === true;
|
|
11210
|
+
}
|
|
11211
|
+
function accumulateBuiltInScanExtensions(buckets, resolveEnabled, resolveSettings, forbidSidecarWriters = false) {
|
|
11175
11212
|
for (const plugin of builtInPlugins) {
|
|
11176
11213
|
for (const ext of plugin.extensions) {
|
|
11177
11214
|
if (!isBuiltInExtensionEnabled(plugin, ext, resolveEnabled)) continue;
|
|
@@ -11189,6 +11226,7 @@ function accumulateBuiltInScanExtensions(buckets, resolveEnabled, resolveSetting
|
|
|
11189
11226
|
buckets.hooks.push(withResolvedSettings(ext, resolveSettings));
|
|
11190
11227
|
break;
|
|
11191
11228
|
case "action":
|
|
11229
|
+
if (forbidSidecarWriters && isSidecarWriterAction(ext)) break;
|
|
11192
11230
|
buckets.actions.push(ext);
|
|
11193
11231
|
break;
|
|
11194
11232
|
case "formatter":
|
|
@@ -18431,7 +18469,8 @@ function registerExtensions(kernel, pluginRuntime, opts, cfg) {
|
|
|
18431
18469
|
const composeOpts = {
|
|
18432
18470
|
noBuiltIns: opts.noBuiltIns,
|
|
18433
18471
|
pluginRuntime,
|
|
18434
|
-
resolveSettings: buildSettingsResolver(cfg)
|
|
18472
|
+
resolveSettings: buildSettingsResolver(cfg),
|
|
18473
|
+
forbidSidecarWriters: cfg.allowSidecarWriters === false
|
|
18435
18474
|
};
|
|
18436
18475
|
if (opts.killSwitches) composeOpts.killSwitches = opts.killSwitches;
|
|
18437
18476
|
if (opts.resolveEnabledOverride) composeOpts.resolveEnabled = opts.resolveEnabledOverride;
|
|
@@ -23644,7 +23683,8 @@ function createWatcherRuntime(opts) {
|
|
|
23644
23683
|
noBuiltIns: opts.noBuiltIns,
|
|
23645
23684
|
pluginRuntime,
|
|
23646
23685
|
resolveEnabled: resolveEnabledOverride,
|
|
23647
|
-
resolveSettings: buildSettingsResolver(cfg)
|
|
23686
|
+
resolveSettings: buildSettingsResolver(cfg),
|
|
23687
|
+
forbidSidecarWriters: cfg.allowSidecarWriters === false
|
|
23648
23688
|
};
|
|
23649
23689
|
if (opts.killSwitches) composeOpts.killSwitches = opts.killSwitches;
|
|
23650
23690
|
const composed = composeScanExtensions(composeOpts);
|
|
@@ -24654,6 +24694,7 @@ var ScanCompareCommand = class extends SmCommand {
|
|
|
24654
24694
|
noBuiltIns: false,
|
|
24655
24695
|
pluginRuntime,
|
|
24656
24696
|
resolveSettings: buildSettingsResolver(cfg),
|
|
24697
|
+
forbidSidecarWriters: cfg.allowSidecarWriters === false,
|
|
24657
24698
|
killSwitches: readConformanceKillSwitches()
|
|
24658
24699
|
});
|
|
24659
24700
|
let current;
|
|
@@ -25120,8 +25161,13 @@ var SERVER_TEXTS = {
|
|
|
25120
25161
|
// silently widen the scan surface.
|
|
25121
25162
|
projectPrefsBodyNotJson: "Request body must be valid JSON.",
|
|
25122
25163
|
projectPrefsBodyNotObject: "Request body must be a JSON object.",
|
|
25123
|
-
projectPrefsBodyEmpty: "Request body must contain a `scan` block with `referencePaths`.",
|
|
25164
|
+
projectPrefsBodyEmpty: "Request body must contain `allowSidecarWriters` and/or a `scan` block with `referencePaths`.",
|
|
25124
25165
|
projectPrefsConfirmNotBoolean: "`confirm` must be a boolean.",
|
|
25166
|
+
projectPrefsSidecarWritersNotBoolean: "`allowSidecarWriters` must be a boolean.",
|
|
25167
|
+
// Server-stderr advisory after `PATCH /api/project-preferences`
|
|
25168
|
+
// toggles the committed sidecar-writer policy. Lets the operator see
|
|
25169
|
+
// the team-shared change land without opening settings.json.
|
|
25170
|
+
projectPrefsSidecarWritersSet: "project-prefs: allowSidecarWriters = {{value}}",
|
|
25125
25171
|
projectPrefsScanNotObject: '`scan` must be an object (e.g. `{"scan": {"referencePaths": ["~/Documents"]}}`).',
|
|
25126
25172
|
projectPrefsListNotArray: "`{{key}}` must be an array of strings.",
|
|
25127
25173
|
projectPrefsListEntryNotString: "`{{key}}` entries must be strings.",
|
|
@@ -26951,6 +26997,10 @@ function registerProjectPreferencesRoute(app, deps) {
|
|
|
26951
26997
|
function buildEnvelope3(deps) {
|
|
26952
26998
|
const cwd = deps.runtimeContext.cwd;
|
|
26953
26999
|
return {
|
|
27000
|
+
allowSidecarWriters: readConfigValue("allowSidecarWriters", {
|
|
27001
|
+
cwd,
|
|
27002
|
+
default: true
|
|
27003
|
+
}) ?? true,
|
|
26954
27004
|
scan: {
|
|
26955
27005
|
referencePaths: readConfigValue("scan.referencePaths", {
|
|
26956
27006
|
cwd,
|
|
@@ -26960,9 +27010,15 @@ function buildEnvelope3(deps) {
|
|
|
26960
27010
|
};
|
|
26961
27011
|
}
|
|
26962
27012
|
async function applyPatch3(deps, body) {
|
|
26963
|
-
const writes = collectWrites(body);
|
|
26964
|
-
if (writes.length === 0) return;
|
|
26965
27013
|
const cwd = deps.runtimeContext.cwd;
|
|
27014
|
+
const policyChanged = typeof body.allowSidecarWriters === "boolean" && writeSidecarWritersPolicy(body.allowSidecarWriters, cwd);
|
|
27015
|
+
const scan = applyScanWrites(body, cwd);
|
|
27016
|
+
if (policyChanged || scan.mutated) await maybeRestartWatcher2(deps);
|
|
27017
|
+
if (policyChanged || scan.attempted) deps.configService.reload();
|
|
27018
|
+
}
|
|
27019
|
+
function applyScanWrites(body, cwd) {
|
|
27020
|
+
const writes = collectWrites(body);
|
|
27021
|
+
if (writes.length === 0) return { attempted: false, mutated: false };
|
|
26966
27022
|
const missingPaths = collectMissingPaths(writes, cwd);
|
|
26967
27023
|
if (missingPaths.length > 0) {
|
|
26968
27024
|
throw new HTTPException12(400, {
|
|
@@ -26980,12 +27036,29 @@ async function applyPatch3(deps, body) {
|
|
|
26980
27036
|
})
|
|
26981
27037
|
});
|
|
26982
27038
|
}
|
|
26983
|
-
let
|
|
27039
|
+
let mutated = false;
|
|
26984
27040
|
for (const w of writes) {
|
|
26985
|
-
if (runWrite(w, cwd))
|
|
27041
|
+
if (runWrite(w, cwd)) mutated = true;
|
|
27042
|
+
}
|
|
27043
|
+
return { attempted: true, mutated };
|
|
27044
|
+
}
|
|
27045
|
+
function writeSidecarWritersPolicy(value, cwd) {
|
|
27046
|
+
const before = readConfigValue("allowSidecarWriters", { cwd, default: true }) ?? true;
|
|
27047
|
+
if (before === value) return false;
|
|
27048
|
+
try {
|
|
27049
|
+
writeConfigValue("allowSidecarWriters", value, { target: "project", cwd });
|
|
27050
|
+
} catch (err) {
|
|
27051
|
+
throw new HTTPException12(400, {
|
|
27052
|
+
message: tx(SERVER_TEXTS.projectPrefsPersistFailed, {
|
|
27053
|
+
key: "allowSidecarWriters",
|
|
27054
|
+
message: formatErrorMessage(err)
|
|
27055
|
+
})
|
|
27056
|
+
});
|
|
26986
27057
|
}
|
|
26987
|
-
|
|
26988
|
-
|
|
27058
|
+
log.warn(
|
|
27059
|
+
tx(SERVER_TEXTS.projectPrefsSidecarWritersSet, { value: String(value) })
|
|
27060
|
+
);
|
|
27061
|
+
return true;
|
|
26989
27062
|
}
|
|
26990
27063
|
function collectWrites(body) {
|
|
26991
27064
|
if (!body.scan) return [];
|
|
@@ -27093,9 +27166,10 @@ function isExistingDirectory(entry, cwd) {
|
|
|
27093
27166
|
var PATCH_BODY_SCHEMA3 = {
|
|
27094
27167
|
type: "object",
|
|
27095
27168
|
additionalProperties: false,
|
|
27096
|
-
required: ["scan"],
|
|
27169
|
+
anyOf: [{ required: ["allowSidecarWriters"] }, { required: ["scan"] }],
|
|
27097
27170
|
properties: {
|
|
27098
27171
|
confirm: { type: "boolean" },
|
|
27172
|
+
allowSidecarWriters: { type: "boolean" },
|
|
27099
27173
|
scan: {
|
|
27100
27174
|
type: "object",
|
|
27101
27175
|
additionalProperties: false,
|
|
@@ -27114,10 +27188,11 @@ var parsePatchBody4 = makeBodyValidator(PATCH_BODY_SCHEMA3, {
|
|
|
27114
27188
|
notObject: SERVER_TEXTS.projectPrefsBodyNotObject,
|
|
27115
27189
|
invalid: SERVER_TEXTS.projectPrefsBodyEmpty,
|
|
27116
27190
|
mapping: {
|
|
27117
|
-
"
|
|
27191
|
+
":anyOf": SERVER_TEXTS.projectPrefsBodyEmpty,
|
|
27118
27192
|
"/scan:minProperties": SERVER_TEXTS.projectPrefsBodyEmpty,
|
|
27119
27193
|
"/scan:type:object": SERVER_TEXTS.projectPrefsScanNotObject,
|
|
27120
27194
|
"/confirm:type:boolean": SERVER_TEXTS.projectPrefsConfirmNotBoolean,
|
|
27195
|
+
"/allowSidecarWriters:type:boolean": SERVER_TEXTS.projectPrefsSidecarWritersNotBoolean,
|
|
27121
27196
|
"/scan/referencePaths:type:array": tx(SERVER_TEXTS.projectPrefsListNotArray, { key: "scan.referencePaths" }),
|
|
27122
27197
|
"/scan/referencePaths/*:type:string": tx(SERVER_TEXTS.projectPrefsListEntryNotString, { key: "scan.referencePaths" }),
|
|
27123
27198
|
"/scan/referencePaths/*:pattern": SERVER_TEXTS.projectPrefsEntryHasComma
|
|
@@ -27349,6 +27424,7 @@ async function materializeWrites(writes, body, cwd) {
|
|
|
27349
27424
|
}
|
|
27350
27425
|
} catch (err) {
|
|
27351
27426
|
if (err instanceof EConsentRequiredError) throw err;
|
|
27427
|
+
if (err instanceof ESidecarWritersForbiddenError) throw err;
|
|
27352
27428
|
throw new HTTPException15(500, { message: formatErrorMessage(err) });
|
|
27353
27429
|
}
|
|
27354
27430
|
}
|
|
@@ -28093,18 +28169,26 @@ function formatError2(err, c) {
|
|
|
28093
28169
|
};
|
|
28094
28170
|
return c.json(envelope, 400);
|
|
28095
28171
|
}
|
|
28172
|
+
const sidecar = formatSidecarConsentError(err, c);
|
|
28173
|
+
if (sidecar) return sidecar;
|
|
28174
|
+
return formatInternalErrorFallThrough(err, c);
|
|
28175
|
+
}
|
|
28176
|
+
function formatSidecarConsentError(err, c) {
|
|
28096
28177
|
if (err instanceof EConsentRequiredError) {
|
|
28097
28178
|
const envelope = {
|
|
28098
28179
|
ok: false,
|
|
28099
|
-
error: {
|
|
28100
|
-
code: "confirm-required",
|
|
28101
|
-
message: err.message,
|
|
28102
|
-
details: { key: err.key }
|
|
28103
|
-
}
|
|
28180
|
+
error: { code: "confirm-required", message: err.message, details: { key: err.key } }
|
|
28104
28181
|
};
|
|
28105
28182
|
return c.json(envelope, 412);
|
|
28106
28183
|
}
|
|
28107
|
-
|
|
28184
|
+
if (err instanceof ESidecarWritersForbiddenError) {
|
|
28185
|
+
const envelope = {
|
|
28186
|
+
ok: false,
|
|
28187
|
+
error: { code: "sidecar-writers-forbidden", message: err.message, details: { key: err.key } }
|
|
28188
|
+
};
|
|
28189
|
+
return c.json(envelope, 403);
|
|
28190
|
+
}
|
|
28191
|
+
return null;
|
|
28108
28192
|
}
|
|
28109
28193
|
function formatConflict(err, c) {
|
|
28110
28194
|
if (err instanceof ActionRefusedError) {
|
|
@@ -30974,4 +31058,4 @@ function resolveBareDefault() {
|
|
|
30974
31058
|
process.exit(ExitCode.Error);
|
|
30975
31059
|
}
|
|
30976
31060
|
//# sourceMappingURL=cli.js.map
|
|
30977
|
-
//# debugId=
|
|
31061
|
+
//# debugId=7e14428f-63d1-5e95-8756-98cea6d3c76e
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// kernel/i18n/registry.texts.ts
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="da133af4-c6e3-580c-95d3-203903628998")}catch(e){}}();
|
|
4
4
|
var REGISTRY_TEXTS = {
|
|
5
5
|
duplicateExtension: "Extension already registered: {{kind}}:{{qualifiedId}}",
|
|
6
6
|
unknownKind: "Unknown extension kind: {{kind}}",
|
|
@@ -102,7 +102,7 @@ import { Tiktoken as Tiktoken2 } from "js-tiktoken/lite";
|
|
|
102
102
|
// package.json
|
|
103
103
|
var package_default = {
|
|
104
104
|
name: "@skill-map/cli",
|
|
105
|
-
version: "0.
|
|
105
|
+
version: "0.60.0",
|
|
106
106
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
107
107
|
license: "MIT",
|
|
108
108
|
type: "module",
|
|
@@ -3845,4 +3845,4 @@ export {
|
|
|
3845
3845
|
runScanWithRenames
|
|
3846
3846
|
};
|
|
3847
3847
|
//# sourceMappingURL=index.js.map
|
|
3848
|
-
//# debugId=
|
|
3848
|
+
//# debugId=da133af4-c6e3-580c-95d3-203903628998
|
package/dist/kernel/index.d.ts
CHANGED
|
@@ -3268,6 +3268,13 @@ type TActionWrite = {
|
|
|
3268
3268
|
path: string;
|
|
3269
3269
|
changes: Record<string, unknown>;
|
|
3270
3270
|
};
|
|
3271
|
+
/**
|
|
3272
|
+
* The discriminant kinds an Action may emit through `IActionResult.writes`.
|
|
3273
|
+
* Today the union has a single member (`'sidecar'`); the alias keeps the
|
|
3274
|
+
* manifest `writes` capability (`IAction.writes`) in lock-step with the
|
|
3275
|
+
* runtime write union so a new write kind only has to be added in one place.
|
|
3276
|
+
*/
|
|
3277
|
+
type TActionWriteKind = TActionWrite['kind'];
|
|
3271
3278
|
interface IActionResult<TReport = unknown> {
|
|
3272
3279
|
report: TReport;
|
|
3273
3280
|
writes?: TActionWrite[];
|
|
@@ -3353,6 +3360,19 @@ interface IAction extends IExtensionBase {
|
|
|
3353
3360
|
* `expectedDurationSeconds` with the `prob*` prefix convention.
|
|
3354
3361
|
*/
|
|
3355
3362
|
probExpectedDurationSeconds?: number;
|
|
3363
|
+
/**
|
|
3364
|
+
* Declared persistent-write capability. Mirrors the `kind`s this
|
|
3365
|
+
* Action's `invoke()` may return in `IActionResult.writes`. Today the
|
|
3366
|
+
* only kind is `'sidecar'` (the Action creates / modifies a `.sm`
|
|
3367
|
+
* annotation sidecar). An Action that returns a sidecar write MUST
|
|
3368
|
+
* declare `['sidecar']` here: the manifest declaration is what
|
|
3369
|
+
* consumers gate on WITHOUT invoking the action, so the
|
|
3370
|
+
* `allowSidecarWriters: false` project policy can drop every
|
|
3371
|
+
* sidecar-writer from the scan composer (its `inspector.action.button`
|
|
3372
|
+
* never projects) and the sidecar store can refuse the write. Absent =
|
|
3373
|
+
* the Action performs no persistent writes (read-only / report-only).
|
|
3374
|
+
*/
|
|
3375
|
+
writes?: TActionWriteKind[];
|
|
3356
3376
|
/**
|
|
3357
3377
|
* Optional declarative filter; absent → applies to every node.
|
|
3358
3378
|
*/
|
package/dist/kernel/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// kernel/i18n/registry.texts.ts
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="694d5ef3-1132-5669-b493-3082eef46469")}catch(e){}}();
|
|
4
4
|
var REGISTRY_TEXTS = {
|
|
5
5
|
duplicateExtension: "Extension already registered: {{kind}}:{{qualifiedId}}",
|
|
6
6
|
unknownKind: "Unknown extension kind: {{kind}}",
|
|
@@ -102,7 +102,7 @@ import { Tiktoken as Tiktoken2 } from "js-tiktoken/lite";
|
|
|
102
102
|
// package.json
|
|
103
103
|
var package_default = {
|
|
104
104
|
name: "@skill-map/cli",
|
|
105
|
-
version: "0.
|
|
105
|
+
version: "0.60.0",
|
|
106
106
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
107
107
|
license: "MIT",
|
|
108
108
|
type: "module",
|
|
@@ -3845,4 +3845,4 @@ export {
|
|
|
3845
3845
|
runScanWithRenames
|
|
3846
3846
|
};
|
|
3847
3847
|
//# sourceMappingURL=index.js.map
|
|
3848
|
-
//# debugId=
|
|
3848
|
+
//# debugId=694d5ef3-1132-5669-b493-3082eef46469
|