@punks/cli 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +158 -89
- package/docs/README.md +1 -2
- package/docs/runbooks/dp-cli-scaffolding.md +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ Current scaffold-managed global tools:
|
|
|
67
67
|
- `portless`
|
|
68
68
|
- `skills`
|
|
69
69
|
|
|
70
|
-
On startup, `punks` checks
|
|
70
|
+
On startup, `punks` starts best-effort checks for a newer CLI version and the `dp-cli` operator skill. CLI package updates prompt before running the inferred package-manager command. The `dp-cli` skill is auto-installed when missing and auto-updated when present through targeted `skills add ... --skill dp-cli` / `skills update dp-cli ...` commands only; startup never runs or suggests plain root `skills update`. Set `DP_NO_UPDATE_CHECK=1` or `DP_NO_SKILL_UPDATE_CHECK=1` to skip those checks.
|
|
71
71
|
|
|
72
72
|
## Publishing
|
|
73
73
|
|
package/dist/index.js
CHANGED
|
@@ -10883,6 +10883,10 @@ var require_public_api = __commonJS((exports) => {
|
|
|
10883
10883
|
exports.stringify = stringify;
|
|
10884
10884
|
});
|
|
10885
10885
|
|
|
10886
|
+
// src/index.ts
|
|
10887
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
10888
|
+
import { createInterface as createInterface3 } from "readline/promises";
|
|
10889
|
+
|
|
10886
10890
|
// node_modules/.pnpm/effect@3.19.19/node_modules/effect/dist/esm/Array.js
|
|
10887
10891
|
var exports_Array = {};
|
|
10888
10892
|
__export(exports_Array, {
|
|
@@ -42283,16 +42287,15 @@ var toolCatalog = [
|
|
|
42283
42287
|
}
|
|
42284
42288
|
];
|
|
42285
42289
|
|
|
42286
|
-
//
|
|
42287
|
-
var
|
|
42288
|
-
var
|
|
42289
|
-
|
|
42290
|
+
// package.json
|
|
42291
|
+
var name = "@punks/cli";
|
|
42292
|
+
var version = "1.0.5";
|
|
42290
42293
|
// src/baseline/bundled.ts
|
|
42291
42294
|
var bundledBaseline = {
|
|
42292
42295
|
summary: {
|
|
42293
42296
|
source: "bundled",
|
|
42294
42297
|
channel: "bundled",
|
|
42295
|
-
version
|
|
42298
|
+
version,
|
|
42296
42299
|
tag: null,
|
|
42297
42300
|
commit: null,
|
|
42298
42301
|
sha256: null
|
|
@@ -42778,8 +42781,8 @@ var collectPackageNames = (pkg) => {
|
|
|
42778
42781
|
if (!record2) {
|
|
42779
42782
|
return;
|
|
42780
42783
|
}
|
|
42781
|
-
for (const
|
|
42782
|
-
names.add(
|
|
42784
|
+
for (const name2 of Object.keys(record2)) {
|
|
42785
|
+
names.add(name2);
|
|
42783
42786
|
}
|
|
42784
42787
|
};
|
|
42785
42788
|
addEntries(pkg.dependencies);
|
|
@@ -43570,12 +43573,13 @@ var renderHint = (value5) => paint(brandPalette.muted, value5);
|
|
|
43570
43573
|
var renderSelfUpdateNotice = ({
|
|
43571
43574
|
currentVersion,
|
|
43572
43575
|
latestVersion,
|
|
43573
|
-
packageName
|
|
43576
|
+
packageName,
|
|
43577
|
+
command
|
|
43574
43578
|
}) => renderPanel("CLI update available", [
|
|
43575
43579
|
`${packageName} ${currentVersion} is behind ${latestVersion}.`,
|
|
43576
43580
|
"",
|
|
43577
43581
|
"usage:",
|
|
43578
|
-
` \u2022 run
|
|
43582
|
+
` \u2022 run \`${command?.join(" ") ?? `npm install -g ${packageName}@latest`}\` to update this CLI`
|
|
43579
43583
|
].join(`
|
|
43580
43584
|
`));
|
|
43581
43585
|
var renderQuestion = (value5) => [
|
|
@@ -44075,8 +44079,8 @@ var packsForWorkspace = ({
|
|
|
44075
44079
|
const dependencyNames = manifest?.dependencies ?? [];
|
|
44076
44080
|
const dependencies = new Set(dependencyNames);
|
|
44077
44081
|
const selectedPacks = new Set(finalPacks);
|
|
44078
|
-
const hasDependency = (
|
|
44079
|
-
const hasDependencyPrefix = (prefix) => dependencyNames.some((
|
|
44082
|
+
const hasDependency = (name2) => dependencies.has(name2);
|
|
44083
|
+
const hasDependencyPrefix = (prefix) => dependencyNames.some((name2) => name2.startsWith(prefix));
|
|
44080
44084
|
const hasBackendDependency = () => hasDependency("better-auth") || hasDependency("drizzle-orm") || hasDependency("drizzle-kit") || hasDependency("elysia") || hasDependencyPrefix("@trpc/");
|
|
44081
44085
|
const hasFrontendDependency = () => hasDependency("next") || hasDependency("react") || hasDependency("react-dom") || hasDependency("@tanstack/react-query");
|
|
44082
44086
|
const hasFrontendWorkspaceName = () => relativeWorkspacePath.split(path8.sep).some((segment) => segment === "frontend" || segment === "ui" || segment === "web") || (manifest?.packageName?.replace(/^@[^/]+\//u, "").split(/[^a-zA-Z0-9]+/u).filter((segment) => segment.length > 0).map((segment) => segment.toLowerCase()).some((segment) => segment === "frontend" || segment === "ui" || segment === "web") ?? false);
|
|
@@ -44682,7 +44686,7 @@ var writeScaffoldOutput = ({
|
|
|
44682
44686
|
lintAssets,
|
|
44683
44687
|
subagentManifestSpec,
|
|
44684
44688
|
baseline: baseline.summary,
|
|
44685
|
-
|
|
44689
|
+
version,
|
|
44686
44690
|
managedFiles,
|
|
44687
44691
|
generatedFiles: manifestGeneratedFiles
|
|
44688
44692
|
})
|
|
@@ -46418,7 +46422,7 @@ var managedFileSchema = Struct({
|
|
|
46418
46422
|
});
|
|
46419
46423
|
var scaffoldManifestSchema = parseJson(Struct({
|
|
46420
46424
|
repoShapeMode: optional(String$),
|
|
46421
|
-
|
|
46425
|
+
version: optional(String$),
|
|
46422
46426
|
finalPacks: Array$(String$),
|
|
46423
46427
|
baseline: optional(Unknown),
|
|
46424
46428
|
generatedFiles: optional(Array$(String$)),
|
|
@@ -46802,7 +46806,7 @@ var readTaggedVersion = async ({
|
|
|
46802
46806
|
try {
|
|
46803
46807
|
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/${encodeURIComponent(tag4)}`, {
|
|
46804
46808
|
headers: {
|
|
46805
|
-
accept: "application/
|
|
46809
|
+
accept: "application/json"
|
|
46806
46810
|
},
|
|
46807
46811
|
signal: controller.signal
|
|
46808
46812
|
});
|
|
@@ -46835,7 +46839,7 @@ var checkSelfUpdate = async ({
|
|
|
46835
46839
|
updateAvailable: isNewerVersion(latestVersion, currentVersion)
|
|
46836
46840
|
};
|
|
46837
46841
|
};
|
|
46838
|
-
var commandExists2 = (command) => spawnSync("which", [command], { stdio: "ignore" }).status === 0;
|
|
46842
|
+
var commandExists2 = (command) => spawnSync("which", [command], { stdio: "ignore", timeout: 750 }).status === 0;
|
|
46839
46843
|
var detectCliInstallPackageManager = ({
|
|
46840
46844
|
entrypoint = process.argv[1] ?? "",
|
|
46841
46845
|
userAgent = process.env.npm_config_user_agent
|
|
@@ -46907,39 +46911,47 @@ var autoUpdateCliIfStale = async ({
|
|
|
46907
46911
|
packageName,
|
|
46908
46912
|
tag: tag4
|
|
46909
46913
|
});
|
|
46910
|
-
const result = spawnSync(command[0], command.slice(1), {
|
|
46911
|
-
stdio: "inherit",
|
|
46912
|
-
shell: false
|
|
46913
|
-
});
|
|
46914
|
-
if (result.status !== 0) {
|
|
46915
|
-
return {
|
|
46916
|
-
status: "failed",
|
|
46917
|
-
check: check2,
|
|
46918
|
-
packageManager,
|
|
46919
|
-
command
|
|
46920
|
-
};
|
|
46921
|
-
}
|
|
46922
46914
|
return {
|
|
46923
|
-
status: "
|
|
46915
|
+
status: "available",
|
|
46924
46916
|
check: check2,
|
|
46925
46917
|
packageManager,
|
|
46926
46918
|
command
|
|
46927
46919
|
};
|
|
46928
46920
|
};
|
|
46929
46921
|
var parseSkillList = (value5) => {
|
|
46930
|
-
|
|
46931
|
-
|
|
46932
|
-
|
|
46922
|
+
try {
|
|
46923
|
+
const parsed = JSON.parse(value5);
|
|
46924
|
+
if (!Array.isArray(parsed)) {
|
|
46925
|
+
return [];
|
|
46926
|
+
}
|
|
46927
|
+
return parsed.flatMap((entry) => {
|
|
46928
|
+
if (typeof entry === "object" && entry !== null && "name" in entry && "path" in entry && "scope" in entry && typeof entry.name === "string" && typeof entry.path === "string" && typeof entry.scope === "string") {
|
|
46929
|
+
return [{
|
|
46930
|
+
name: entry.name,
|
|
46931
|
+
path: entry.path,
|
|
46932
|
+
scope: entry.scope
|
|
46933
|
+
}];
|
|
46934
|
+
}
|
|
46935
|
+
return [];
|
|
46936
|
+
});
|
|
46937
|
+
} catch {
|
|
46938
|
+
return parseTextSkillList(value5);
|
|
46933
46939
|
}
|
|
46934
|
-
|
|
46935
|
-
|
|
46936
|
-
|
|
46937
|
-
|
|
46938
|
-
|
|
46939
|
-
|
|
46940
|
-
|
|
46940
|
+
};
|
|
46941
|
+
var stripAnsi = (value5) => value5.replace(/\x1B\[[0-?]*[ -/]*[@-~]/gu, "");
|
|
46942
|
+
var parseTextSkillList = (value5) => {
|
|
46943
|
+
const scope5 = value5.includes("Global Skills") ? "global" : "project";
|
|
46944
|
+
return stripAnsi(value5).split(`
|
|
46945
|
+
`).flatMap((line4) => {
|
|
46946
|
+
const match18 = line4.match(/^([^\s]+)\s+(.+)$/u);
|
|
46947
|
+
if (match18 === null || match18[1] === "Project" || match18[1] === "Global") {
|
|
46948
|
+
return [];
|
|
46941
46949
|
}
|
|
46942
|
-
return [
|
|
46950
|
+
return [{
|
|
46951
|
+
name: match18[1],
|
|
46952
|
+
path: match18[2].trim(),
|
|
46953
|
+
scope: scope5
|
|
46954
|
+
}];
|
|
46943
46955
|
});
|
|
46944
46956
|
};
|
|
46945
46957
|
var listSkills = (scope5) => {
|
|
@@ -46948,66 +46960,82 @@ var listSkills = (scope5) => {
|
|
|
46948
46960
|
encoding: "utf8",
|
|
46949
46961
|
shell: false,
|
|
46950
46962
|
stdio: ["ignore", "pipe", "ignore"],
|
|
46951
|
-
timeout:
|
|
46963
|
+
timeout: 1500
|
|
46952
46964
|
});
|
|
46953
46965
|
if (result.status !== 0) {
|
|
46954
46966
|
return [];
|
|
46955
46967
|
}
|
|
46956
|
-
|
|
46957
|
-
|
|
46958
|
-
|
|
46959
|
-
|
|
46960
|
-
|
|
46961
|
-
|
|
46962
|
-
|
|
46963
|
-
|
|
46964
|
-
|
|
46968
|
+
return parseSkillList(result.stdout);
|
|
46969
|
+
};
|
|
46970
|
+
var skillUpdateCommand = (scope5) => scope5 === "global" ? ["skills", "update", "dp-cli", "--global", "--yes"] : ["skills", "update", "dp-cli", "--project", "--yes"];
|
|
46971
|
+
var skillInstallCommand = () => [
|
|
46972
|
+
"skills",
|
|
46973
|
+
"add",
|
|
46974
|
+
"wearedevpunks/skills",
|
|
46975
|
+
"--global",
|
|
46976
|
+
"--skill",
|
|
46977
|
+
"dp-cli",
|
|
46978
|
+
"--yes"
|
|
46979
|
+
];
|
|
46980
|
+
var runSkillsCommand = (command) => {
|
|
46981
|
+
const result = spawnSync(command[0], command.slice(1), {
|
|
46965
46982
|
stdio: "ignore",
|
|
46966
46983
|
shell: false,
|
|
46967
46984
|
timeout: 30000
|
|
46968
46985
|
});
|
|
46969
46986
|
return result.status === 0;
|
|
46970
46987
|
};
|
|
46988
|
+
var updateDpCliSkill = (scope5) => runSkillsCommand(skillUpdateCommand(scope5));
|
|
46971
46989
|
var installDpCliSkillGlobal = () => {
|
|
46972
|
-
|
|
46973
|
-
"add",
|
|
46974
|
-
"wearedevpunks/skills",
|
|
46975
|
-
"--global",
|
|
46976
|
-
"--skill",
|
|
46977
|
-
"dp-cli",
|
|
46978
|
-
"--yes"
|
|
46979
|
-
], {
|
|
46980
|
-
stdio: "ignore",
|
|
46981
|
-
shell: false,
|
|
46982
|
-
timeout: 30000
|
|
46983
|
-
});
|
|
46984
|
-
return result.status === 0;
|
|
46990
|
+
return runSkillsCommand(skillInstallCommand());
|
|
46985
46991
|
};
|
|
46986
|
-
var
|
|
46992
|
+
var checkDpCliSkillPresence = () => {
|
|
46987
46993
|
if (!commandExists2("skills")) {
|
|
46988
46994
|
return {
|
|
46989
46995
|
skillsCliAvailable: false,
|
|
46990
46996
|
detected: false,
|
|
46991
46997
|
project: false,
|
|
46992
|
-
global: false
|
|
46993
|
-
installedGlobal: false,
|
|
46994
|
-
updatedProject: false,
|
|
46995
|
-
updatedGlobal: false
|
|
46998
|
+
global: false
|
|
46996
46999
|
};
|
|
46997
47000
|
}
|
|
46998
47001
|
const projectBeforeInstall = listSkills("project").some((skill) => skill.name === "dp-cli");
|
|
46999
47002
|
const globalBeforeInstall = listSkills("global").some((skill) => skill.name === "dp-cli");
|
|
47000
|
-
const installedGlobal = projectBeforeInstall || globalBeforeInstall ? false : installDpCliSkillGlobal();
|
|
47001
47003
|
const project3 = projectBeforeInstall;
|
|
47002
|
-
const global = globalBeforeInstall
|
|
47004
|
+
const global = globalBeforeInstall;
|
|
47003
47005
|
return {
|
|
47004
47006
|
skillsCliAvailable: true,
|
|
47005
47007
|
detected: project3 || global,
|
|
47006
47008
|
project: project3,
|
|
47007
|
-
global
|
|
47008
|
-
|
|
47009
|
-
|
|
47010
|
-
|
|
47009
|
+
global
|
|
47010
|
+
};
|
|
47011
|
+
};
|
|
47012
|
+
var maintainDpCliSkill = () => {
|
|
47013
|
+
const presence = checkDpCliSkillPresence();
|
|
47014
|
+
if (!presence.skillsCliAvailable) {
|
|
47015
|
+
return {
|
|
47016
|
+
...presence,
|
|
47017
|
+
installedGlobal: false,
|
|
47018
|
+
updatedProject: false,
|
|
47019
|
+
updatedGlobal: false
|
|
47020
|
+
};
|
|
47021
|
+
}
|
|
47022
|
+
if (!presence.detected) {
|
|
47023
|
+
const installedGlobal = installDpCliSkillGlobal();
|
|
47024
|
+
return {
|
|
47025
|
+
skillsCliAvailable: true,
|
|
47026
|
+
detected: installedGlobal,
|
|
47027
|
+
project: false,
|
|
47028
|
+
global: installedGlobal,
|
|
47029
|
+
installedGlobal,
|
|
47030
|
+
updatedProject: false,
|
|
47031
|
+
updatedGlobal: installedGlobal ? updateDpCliSkill("global") : false
|
|
47032
|
+
};
|
|
47033
|
+
}
|
|
47034
|
+
return {
|
|
47035
|
+
...presence,
|
|
47036
|
+
installedGlobal: false,
|
|
47037
|
+
updatedProject: presence.project ? updateDpCliSkill("project") : false,
|
|
47038
|
+
updatedGlobal: presence.global ? updateDpCliSkill("global") : false
|
|
47011
47039
|
};
|
|
47012
47040
|
};
|
|
47013
47041
|
|
|
@@ -47015,31 +47043,72 @@ var ensureDpCliSkillPresent = () => {
|
|
|
47015
47043
|
var app = exports_Command.make("punks", {}, () => exports_Effect.sync(() => console.log(renderCommandGuide()))).pipe(exports_Command.withDescription("Devpunks AI scaffolding CLI."), exports_Command.withSubcommands([scaffoldCommand, updateCommand]));
|
|
47016
47044
|
var cli = exports_Command.run(app, {
|
|
47017
47045
|
name: "punks",
|
|
47018
|
-
version
|
|
47046
|
+
version
|
|
47019
47047
|
});
|
|
47020
47048
|
var shouldCheckSelfUpdate = () => process.env.DP_NO_UPDATE_CHECK !== "1" && process.env.CI === undefined && process.argv.includes("--help") === false && process.argv.includes("-h") === false && process.argv.includes("--version") === false && process.argv.includes("-v") === false;
|
|
47021
|
-
var
|
|
47022
|
-
|
|
47023
|
-
return;
|
|
47024
|
-
}
|
|
47049
|
+
var shouldCheckDpCliSkillUpdate = () => process.env.DP_NO_SKILL_UPDATE_CHECK !== "1" && process.env.CI === undefined && process.argv.includes("--help") === false && process.argv.includes("-h") === false && process.argv.includes("--version") === false && process.argv.includes("-v") === false;
|
|
47050
|
+
var runCliUpdateCheck = async () => {
|
|
47025
47051
|
const result = await autoUpdateCliIfStale({
|
|
47026
|
-
currentVersion:
|
|
47027
|
-
packageName:
|
|
47052
|
+
currentVersion: version,
|
|
47053
|
+
packageName: name,
|
|
47028
47054
|
tag: process.env.DP_UPDATE_TAG ?? "latest"
|
|
47029
47055
|
});
|
|
47030
|
-
if (result.status === "manager-not-detected" || result.status === "failed") {
|
|
47056
|
+
if (result.status === "available" || result.status === "manager-not-detected" || result.status === "failed") {
|
|
47031
47057
|
console.error(renderSelfUpdateNotice({
|
|
47032
47058
|
currentVersion: result.check.currentVersion,
|
|
47033
47059
|
latestVersion: result.check.latestVersion,
|
|
47034
|
-
packageName: result.check.packageName
|
|
47060
|
+
packageName: result.check.packageName,
|
|
47061
|
+
command: result.command
|
|
47035
47062
|
}));
|
|
47036
47063
|
}
|
|
47037
|
-
|
|
47038
|
-
var shouldCheckDpCliSkillUpdate = () => process.env.DP_NO_SKILL_UPDATE_CHECK !== "1" && process.env.CI === undefined && process.argv.includes("--help") === false && process.argv.includes("-h") === false && process.argv.includes("--version") === false && process.argv.includes("-v") === false;
|
|
47039
|
-
var dpCliSkillUpdate = exports_Effect.sync(() => {
|
|
47040
|
-
if (!shouldCheckDpCliSkillUpdate()) {
|
|
47064
|
+
if (result.status !== "available" || process.stdin.isTTY !== true) {
|
|
47041
47065
|
return;
|
|
47042
47066
|
}
|
|
47043
|
-
|
|
47044
|
-
|
|
47045
|
-
|
|
47067
|
+
const prompt4 = createInterface3({
|
|
47068
|
+
input: process.stdin,
|
|
47069
|
+
output: process.stderr
|
|
47070
|
+
});
|
|
47071
|
+
try {
|
|
47072
|
+
const answer = await prompt4.question("Update punks CLI now? [y/N]: ");
|
|
47073
|
+
if (!["y", "yes"].includes(answer.trim().toLowerCase())) {
|
|
47074
|
+
return;
|
|
47075
|
+
}
|
|
47076
|
+
console.error(`punks startup checks: running \`${result.command.join(" ")}\``);
|
|
47077
|
+
const update5 = spawnSync2(result.command[0], result.command.slice(1), {
|
|
47078
|
+
stdio: "inherit",
|
|
47079
|
+
shell: false
|
|
47080
|
+
});
|
|
47081
|
+
if (update5.status !== 0) {
|
|
47082
|
+
console.error("punks startup checks: CLI update failed.");
|
|
47083
|
+
}
|
|
47084
|
+
} finally {
|
|
47085
|
+
prompt4.close();
|
|
47086
|
+
}
|
|
47087
|
+
};
|
|
47088
|
+
var runDpCliSkillCheck = () => {
|
|
47089
|
+
const skillResult = maintainDpCliSkill();
|
|
47090
|
+
if (!skillResult.skillsCliAvailable) {
|
|
47091
|
+
return;
|
|
47092
|
+
}
|
|
47093
|
+
if (skillResult.installedGlobal) {
|
|
47094
|
+
console.error("punks startup checks: installed `dp-cli` skill globally.");
|
|
47095
|
+
}
|
|
47096
|
+
if (skillResult.updatedProject || skillResult.updatedGlobal) {
|
|
47097
|
+
console.error("punks startup checks: updated `dp-cli` skill.");
|
|
47098
|
+
}
|
|
47099
|
+
};
|
|
47100
|
+
var runStartupChecks = async () => {
|
|
47101
|
+
const checkCli = shouldCheckSelfUpdate();
|
|
47102
|
+
const checkSkill = shouldCheckDpCliSkillUpdate();
|
|
47103
|
+
if (!checkCli && !checkSkill) {
|
|
47104
|
+
return;
|
|
47105
|
+
}
|
|
47106
|
+
if (checkSkill) {
|
|
47107
|
+
setTimeout(runDpCliSkillCheck, 0);
|
|
47108
|
+
}
|
|
47109
|
+
if (checkCli) {
|
|
47110
|
+
await runCliUpdateCheck();
|
|
47111
|
+
}
|
|
47112
|
+
};
|
|
47113
|
+
runStartupChecks().catch(() => {});
|
|
47114
|
+
cli(process.argv).pipe(exports_Effect.provide(exports_Layer.mergeAll(exports_BunContext.layer)), exports_BunRuntime.runMain);
|
package/docs/README.md
CHANGED
|
@@ -11,8 +11,7 @@ Implementation notes:
|
|
|
11
11
|
- distributed skill assets live in `skills/`
|
|
12
12
|
- runtime projection/writing logic lives in `src/scaffold/`
|
|
13
13
|
- `punks update` refreshes scaffold-managed assets from `.devpunks/scaffold-manifest.json`
|
|
14
|
-
- CLI startup checks npm's `latest` dist-tag
|
|
15
|
-
- CLI startup also checks for the `dp-cli` skill through the `skills` CLI, installing it globally when absent and updating it when present. Set `DP_NO_SKILL_UPDATE_CHECK=1` to skip this best-effort pass.
|
|
14
|
+
- CLI startup checks npm's `latest` dist-tag and prompts before CLI package updates; it auto-installs/updates only the named `dp-cli` skill through targeted `skills add ... --skill dp-cli` / `skills update dp-cli ...` commands. Set `DP_NO_UPDATE_CHECK=1` or `DP_NO_SKILL_UPDATE_CHECK=1` to skip those checks, and `DP_UPDATE_TAG=next` to compare against another dist-tag.
|
|
16
15
|
- baseline releases use `baseline/stable/*` GitHub release tags, separate from npm executable tags such as `v1.0.1`
|
|
17
16
|
- shared neutral hook and sync assets live in `src/data/hooks/` and `src/data/scripts/`
|
|
18
17
|
- scaffolded required tools always include `portless` and `skills` so generated guidance can standardize local dev origins and keep skill entrypoints up to date
|
|
@@ -217,11 +217,11 @@ The npm account must have publish access to `@punks/cli`; otherwise npm may repo
|
|
|
217
217
|
|
|
218
218
|
## CLI Self-Update Detection
|
|
219
219
|
|
|
220
|
-
The CLI also
|
|
220
|
+
The CLI also starts best-effort startup checks on normal command startup. It checks the npm package version for `@punks/cli`, and it checks the `dp-cli` skill through the `skills` CLI. CLI package updates require an interactive `y/N` confirmation before running the inferred package-manager command. The `dp-cli` skill is auto-installed when missing and auto-updated when present, but only through targeted `skills add ... --skill dp-cli` / `skills update dp-cli ...` commands. Startup must never run or suggest plain root `skills update`. These checks are separate from `punks update`, which updates scaffold-managed repo assets.
|
|
221
221
|
|
|
222
222
|
- checks `https://registry.npmjs.org/%40punks%2Fcli/latest`
|
|
223
223
|
- compares that dist-tag version with the bundled CLI version
|
|
224
|
-
-
|
|
224
|
+
- prompts to run the inferred package-manager command only when the registry version is newer
|
|
225
225
|
- silently skips the notice when npm is unreachable, the registry response is invalid, or the command is `--help` / `--version`
|
|
226
226
|
- skips in CI and when `DP_NO_UPDATE_CHECK=1`
|
|
227
227
|
- supports `DP_UPDATE_TAG=next` for canary/operator testing against another dist-tag
|