@joshuafolkken/kit 1.1094.0 → 1.1136.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/.claude/agents/investigator.md +17 -0
- package/.claude/settings.json +1 -0
- package/.claude/skills/workflow-commands/SKILL.md +1 -1
- package/.claude/skills/workflow-commands/background-commands.md +36 -85
- package/.claude/skills/workflow-commands/backlogrun-progress.md +31 -34
- package/.claude/skills/workflow-commands/backlogrun-steps.md +2 -2
- package/.claude/skills/workflow-commands/delegation.md +5 -1
- package/.claude/skills/workflow-commands/fullrun.md +5 -4
- package/.claude/skills/workflow-commands/halfrun.md +5 -4
- package/.claude/skills/workflow-commands/latest-gate.md +7 -15
- package/.claude/skills/workflow-commands/pre-gate-cut.md +4 -8
- package/.claude/skills/workflow-commands/split-assessment.md +4 -18
- package/.github/actions/setup-node/action.yml +33 -0
- package/.github/actions/setup-pnpm/action.yml +4 -4
- package/.github/workflows/auto-tag.yml +2 -3
- package/.github/workflows/ci.yml +7 -8
- package/.github/workflows/dependabot-auto-merge.yml +1 -0
- package/.github/workflows/pr-classification.yml +1 -3
- package/.github/workflows/production.yml +1 -0
- package/.github/workflows/publish.yml +10 -9
- package/.github/workflows/sonar-qube.yml +17 -13
- package/.pnpmfile.mjs +29 -0
- package/AGENTS.md +4 -11
- package/CLAUDE.md +24 -17
- package/GEMINI.md +4 -13
- package/README.md +8 -3
- package/SECURITY.md +2 -0
- package/cspell/index.yaml +4 -0
- package/dist/CLAUDE.basic.md +6 -6
- package/dist/CLAUDE.md +24 -17
- package/dist/CLAUDE.static.md +6 -6
- package/dist/config-merge/index.js +33 -9
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-OIZUHPJI.js → chunk-FO2I7UT7.js} +1 -1
- package/dist/hooks/{chunk-NKOG3XAV.js → chunk-GDU26K3J.js} +11 -3
- package/dist/hooks/{chunk-O4LL4HTI.js → chunk-HANSKHES.js} +2 -2
- package/dist/hooks/{chunk-3C4YCCEF.js → chunk-HBKZLITF.js} +4 -4
- package/dist/hooks/{chunk-UD24EAIL.js → chunk-JKKTVDAG.js} +1984 -146
- package/dist/hooks/{chunk-M2XDCUKD.js → chunk-KBXZLMRH.js} +89 -1803
- package/dist/hooks/{chunk-IL27YTPH.js → chunk-KOKOAV6D.js} +2 -2
- package/dist/hooks/{chunk-7ZPFAVR7.js → chunk-LJBLGHEH.js} +59 -19
- package/dist/hooks/{chunk-E54KGFEQ.js → chunk-NFZGFGOR.js} +1 -1
- package/dist/hooks/{chunk-KHWHKJOM.js → chunk-RFWWUI5F.js} +4 -4
- package/dist/hooks/codex-hook-adapter.js +12 -47
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/inputs.json +175 -173
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +9 -9
- package/dist/hooks/stop-guard.js +17 -12
- package/dist/josh.js +87 -31
- package/dist/version/index.js +36 -20
- package/eslint/rules/unicorn.js +3 -2
- package/package.json +23 -5
- package/pnpm-workspace.yaml +5 -7
- package/prompts/collaboration-workflow/glossary.md +17 -0
- package/prompts/collaboration-workflow/issue-template.md +1 -1
- package/prompts/collaboration-workflow/operating-rules.md +1 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow.md +1 -0
- package/scripts/backlog/backlog-arrival.ts +30 -10
- package/scripts/backlog/backlog-budget-cli.ts +15 -16
- package/scripts/backlog/backlog-offer-cli.ts +6 -14
- package/scripts/backlog/backlog-plan.ts +29 -18
- package/scripts/backlog/backlog-ready.ts +20 -7
- package/scripts/config-merge/parse-jsonc.ts +33 -3
- package/scripts/config-merge/patch-json-key.ts +13 -6
- package/scripts/cost-runtime/cost-cli.ts +3 -7
- package/scripts/delegation/delegation-policy.ts +9 -1
- package/scripts/delegation/investigation-guard.ts +1 -1
- package/scripts/delegation/investigation-reads.ts +105 -19
- package/scripts/doctor/doctor-consumer.ts +3 -5
- package/scripts/doctor/doctor-io.ts +9 -13
- package/scripts/document/backlogrun-parent-read-set.ts +12 -1
- package/scripts/document/capped-print.ts +74 -0
- package/scripts/document/document-byte-budget.ts +1 -0
- package/scripts/document/document-section-cli.ts +4 -3
- package/scripts/document/entry-read-budget.ts +13 -7
- package/scripts/document/entry-read-set.ts +32 -8
- package/scripts/document/lane-child-read-set.ts +7 -0
- package/scripts/document/read-set-point-of-use.ts +8 -3
- package/scripts/document/read-set-trim.ts +3 -1
- package/scripts/epic/epic-audit.ts +3 -18
- package/scripts/gate/scoped-green.ts +25 -14
- package/scripts/gh/git-gh-issue-list.ts +12 -11
- package/scripts/gh/git-gh-issue-write.ts +4 -1
- package/scripts/gh/git-gh-pr-auto-merge.ts +4 -1
- package/scripts/git/git-command.ts +6 -1
- package/scripts/git/git-spawn-sync.ts +65 -0
- package/scripts/git/git-spawn.ts +5 -4
- package/scripts/git/stash/stash-pop-args.ts +1 -6
- package/scripts/init/claude-kit-only-settings.ts +29 -0
- package/scripts/init/init-copy-content.ts +8 -2
- package/scripts/init/init-file-action.ts +54 -0
- package/scripts/init/init-logic-migrate.ts +35 -17
- package/scripts/init/init-logic-secretlint.ts +1 -1
- package/scripts/init/init-logic.ts +6 -22
- package/scripts/init/init.ts +11 -68
- package/scripts/init/initial-commit.ts +24 -0
- package/scripts/init/kit-written-paths.ts +2 -0
- package/scripts/init/project-profile.ts +3 -6
- package/scripts/init/start-exec.ts +16 -3
- package/scripts/init/start-steps.ts +10 -13
- package/scripts/issue/defect-rate-cli.ts +61 -20
- package/scripts/issue/issue-backlinks.ts +7 -14
- package/scripts/issue/issue-cite.ts +12 -6
- package/scripts/issue/issue-file.ts +5 -12
- package/scripts/issue/issue-read-cli.ts +1 -0
- package/scripts/issue/issue-report-failures.ts +6 -2
- package/scripts/issue/issue-state-cli.ts +1 -1
- package/scripts/issue/markdown-section.ts +21 -6
- package/scripts/issue/measure-rerun-cli.ts +73 -14
- package/scripts/josh/josh-commands-lane.ts +1 -1
- package/scripts/josh/josh-commands-project.ts +8 -1
- package/scripts/josh/josh-commands-workflow.ts +1 -1
- package/scripts/josh/run-github-prerequisite.ts +3 -6
- package/scripts/lane/lane-await.ts +89 -15
- package/scripts/lane/lane-cli.ts +11 -13
- package/scripts/lane/lane-close.ts +4 -1
- package/scripts/lane/lane-launch-cli.ts +10 -16
- package/scripts/lane/openai-review-broker.ts +4 -1
- package/scripts/lib/cli-flags.ts +31 -2
- package/scripts/lib/error-message.ts +12 -1
- package/scripts/lines/line-targets.ts +0 -11
- package/scripts/lines/lines-command.ts +5 -3
- package/scripts/propagate/propagate-git.ts +3 -8
- package/scripts/refactor/refactor-scan.ts +2 -1
- package/scripts/registry-migration/migrate-logic.ts +28 -19
- package/scripts/registry-migration/migrate.ts +6 -5
- package/scripts/release/github-release-cli.ts +14 -3
- package/scripts/release/github-release-environment.ts +1 -0
- package/scripts/release/github-release.ts +103 -17
- package/scripts/release/release-publish.ts +36 -2
- package/scripts/release/release-worktree.ts +97 -2
- package/scripts/review/review-checkout.ts +3 -2
- package/scripts/review/review-record-cli.ts +9 -16
- package/scripts/rules/early-heartbeat.ts +4 -3
- package/scripts/rules/lane-park.ts +9 -0
- package/scripts/rules/stop-rules.ts +7 -4
- package/scripts/run/run-carry-args.ts +8 -12
- package/scripts/run/run-carry-cli.ts +3 -1
- package/scripts/run/run-carry-conversation.ts +94 -0
- package/scripts/run/run-carry-reclaim.ts +37 -0
- package/scripts/run/run-carry.ts +21 -5
- package/scripts/run/run-cut-args.ts +1 -6
- package/scripts/run/run-ending-cli.ts +1 -5
- package/scripts/run/run-entry-cli.ts +40 -9
- package/scripts/run/run-entry-stop.ts +104 -0
- package/scripts/run/run-event-stream-emit.ts +7 -2
- package/scripts/run/run-hold.ts +4 -1
- package/scripts/run/run-liveness-cli.ts +1 -5
- package/scripts/run/run-merge-cli.ts +2 -10
- package/scripts/run/run-merge-steps.ts +4 -1
- package/scripts/run/run-parent-cut-hook.ts +4 -1
- package/scripts/run/run-prep-cli.ts +4 -1
- package/scripts/run/run-progress-args.ts +20 -4
- package/scripts/run/run-progress-cli.ts +31 -29
- package/scripts/run/run-progress-clock.ts +4 -1
- package/scripts/run/run-ship-cli.ts +8 -16
- package/scripts/run/run-ship-probe.ts +4 -1
- package/scripts/run/run-status-cli.ts +2 -15
- package/scripts/run/run-tidy-lanes.ts +4 -1
- package/scripts/run/run-wake-cli.ts +2 -10
- package/scripts/run/run-watcher-guard.ts +9 -5
- package/scripts/safe-chain/pack-hook.ts +92 -0
- package/scripts/sync/sync-ai-files.ts +4 -0
- package/scripts/test/test-declared-changed.ts +13 -16
- package/scripts/test/test-declared.ts +3 -7
- package/scripts/test/test-related.ts +1 -6
- package/scripts/test/test-unit-guard.ts +21 -7
- package/scripts/time-runtime/time-spans.ts +4 -0
- package/scripts/version/version-commands.ts +11 -1
- package/templates/CLAUDE.basic.md +6 -6
- package/templates/workflows/ci.yml +16 -82
- package/templates/workflows/dependabot-auto-merge.yml +1 -0
- package/templates/workflows/github-release.yml +14 -28
- package/tsconfig.sonar.json +4 -22
package/dist/josh.js
CHANGED
|
@@ -4,6 +4,74 @@
|
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
|
|
7
|
+
// scripts/lib/spawn-exit.ts
|
|
8
|
+
var SPAWN_ERROR_EXIT_CODE = 2;
|
|
9
|
+
var SIGNAL_KILL_EXIT_CODE = 1;
|
|
10
|
+
function resolve_spawn_exit(executable, result) {
|
|
11
|
+
if (result.exitCode !== void 0) return result.exitCode;
|
|
12
|
+
if (result.isTerminated === true) return SIGNAL_KILL_EXIT_CODE;
|
|
13
|
+
console.error(`Failed to execute ${executable}: ${result.shortMessage ?? "spawn failed"}`);
|
|
14
|
+
return SPAWN_ERROR_EXIT_CODE;
|
|
15
|
+
}
|
|
16
|
+
function read_spawn_stdout(result) {
|
|
17
|
+
return result.stdout ?? "";
|
|
18
|
+
}
|
|
19
|
+
function read_spawn_stderr(result) {
|
|
20
|
+
return result.stderr ?? "";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// scripts/git/git-spawn-sync.ts
|
|
24
|
+
import { execaSync } from "execa";
|
|
25
|
+
|
|
26
|
+
// scripts/git/constants.ts
|
|
27
|
+
import { platform } from "node:os";
|
|
28
|
+
var GIT_COMMAND_UNIX = "/usr/bin/git";
|
|
29
|
+
function get_git_command() {
|
|
30
|
+
if (platform() === "win32") {
|
|
31
|
+
return String.raw`"C:\Program Files\Git\cmd\git.exe"`;
|
|
32
|
+
}
|
|
33
|
+
return GIT_COMMAND_UNIX;
|
|
34
|
+
}
|
|
35
|
+
function get_git_command_for_spawn() {
|
|
36
|
+
if (platform() === "win32") {
|
|
37
|
+
return String.raw`C:\Program Files\Git\cmd\git.exe`;
|
|
38
|
+
}
|
|
39
|
+
return GIT_COMMAND_UNIX;
|
|
40
|
+
}
|
|
41
|
+
var git_utilities = {
|
|
42
|
+
get_git_command,
|
|
43
|
+
get_git_command_for_spawn
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// scripts/git/git-spawn-sync.ts
|
|
47
|
+
var GIT_TIMEOUT_MS = 1e4;
|
|
48
|
+
var SUCCESS_EXIT_CODE = 0;
|
|
49
|
+
var C_LOCALE = { LC_ALL: "C", LANGUAGE: "C" };
|
|
50
|
+
function run(args, options = {}) {
|
|
51
|
+
const result = execaSync(git_utilities.get_git_command_for_spawn(), args, {
|
|
52
|
+
...options,
|
|
53
|
+
extendEnv: true,
|
|
54
|
+
reject: false,
|
|
55
|
+
timeout: options.timeout ?? GIT_TIMEOUT_MS
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
exit_code: result.exitCode,
|
|
59
|
+
stdout: read_spawn_stdout(result),
|
|
60
|
+
stderr: read_spawn_stderr(result)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function read(args, options = {}) {
|
|
64
|
+
const result = run(args, options);
|
|
65
|
+
return result.exit_code === SUCCESS_EXIT_CODE ? result.stdout.trim() : void 0;
|
|
66
|
+
}
|
|
67
|
+
function origin_url(cwd) {
|
|
68
|
+
return read(["config", "--get", "remote.origin.url"], { cwd });
|
|
69
|
+
}
|
|
70
|
+
function toplevel(timeout = GIT_TIMEOUT_MS) {
|
|
71
|
+
return run(["rev-parse", "--show-toplevel"], { env: C_LOCALE, timeout });
|
|
72
|
+
}
|
|
73
|
+
var git_spawn_sync = { GIT_TIMEOUT_MS, C_LOCALE, run, read, origin_url, toplevel };
|
|
74
|
+
|
|
7
75
|
// scripts/lib/json-value.ts
|
|
8
76
|
function parse_or_undefined(text) {
|
|
9
77
|
try {
|
|
@@ -43,24 +111,10 @@ function read_if_readable(path5) {
|
|
|
43
111
|
}
|
|
44
112
|
var file_reader = { read_optional, read_file_or_empty, read_if_readable };
|
|
45
113
|
|
|
46
|
-
// scripts/lib/spawn-exit.ts
|
|
47
|
-
var SPAWN_ERROR_EXIT_CODE = 2;
|
|
48
|
-
var SIGNAL_KILL_EXIT_CODE = 1;
|
|
49
|
-
function resolve_spawn_exit(executable, result) {
|
|
50
|
-
if (result.exitCode !== void 0) return result.exitCode;
|
|
51
|
-
if (result.isTerminated === true) return SIGNAL_KILL_EXIT_CODE;
|
|
52
|
-
console.error(`Failed to execute ${executable}: ${result.shortMessage ?? "spawn failed"}`);
|
|
53
|
-
return SPAWN_ERROR_EXIT_CODE;
|
|
54
|
-
}
|
|
55
|
-
function read_spawn_stdout(result) {
|
|
56
|
-
return result.stdout ?? "";
|
|
57
|
-
}
|
|
58
|
-
|
|
59
114
|
// scripts/version/kit-descriptor.ts
|
|
60
115
|
var KIT_PACKAGE_NAME = "@joshuafolkken/kit";
|
|
61
116
|
|
|
62
117
|
// scripts/doctor/doctor-consumer.ts
|
|
63
|
-
import { execaSync } from "execa";
|
|
64
118
|
import { z } from "zod";
|
|
65
119
|
var NODE_MODULES = "node_modules";
|
|
66
120
|
var SETTINGS_PATH = path.join(".claude", "settings.json");
|
|
@@ -68,7 +122,7 @@ var CLAUDE_MD = "CLAUDE.md";
|
|
|
68
122
|
var PLUGIN_ID = "kit@kit";
|
|
69
123
|
var CLAUDE_MD_POINTER = `@${NODE_MODULES}/${KIT_PACKAGE_NAME}/dist/${CLAUDE_MD}`;
|
|
70
124
|
var SECRETLINT_BIN = path.join(NODE_MODULES, ".bin", "secretlint");
|
|
71
|
-
var
|
|
125
|
+
var GIT_TIMEOUT_MS2 = 2e3;
|
|
72
126
|
var manifest_schema = z.object({
|
|
73
127
|
name: z.string().optional(),
|
|
74
128
|
dependencies: z.record(z.string(), z.string()).optional(),
|
|
@@ -102,11 +156,9 @@ function is_plugin_declared(root) {
|
|
|
102
156
|
return parsed.success && parsed.data.enabledPlugins?.[PLUGIN_ID] === true;
|
|
103
157
|
}
|
|
104
158
|
function configured_hooks_path(root) {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
timeout: GIT_TIMEOUT_MS
|
|
159
|
+
const value = git_spawn_sync.read(["-C", root, "config", "--get", "core.hooksPath"], {
|
|
160
|
+
timeout: GIT_TIMEOUT_MS2
|
|
108
161
|
});
|
|
109
|
-
const value = read_spawn_stdout(result).trim();
|
|
110
162
|
return value === "" ? void 0 : value;
|
|
111
163
|
}
|
|
112
164
|
function claude_md_state(root) {
|
|
@@ -166,6 +218,7 @@ function report_consumer_setup(root) {
|
|
|
166
218
|
var doctor_consumer = {
|
|
167
219
|
claude_md_line,
|
|
168
220
|
claude_md_state,
|
|
221
|
+
configured_hooks_path,
|
|
169
222
|
hooks_path_line,
|
|
170
223
|
is_kit_consumer,
|
|
171
224
|
is_plugin_declared,
|
|
@@ -246,7 +299,7 @@ function resolve_package_bin(base_directory, package_name, bin_name) {
|
|
|
246
299
|
}
|
|
247
300
|
|
|
248
301
|
// scripts/josh/josh-logic.ts
|
|
249
|
-
import { execaSync as
|
|
302
|
+
import { execaSync as execaSync2 } from "execa";
|
|
250
303
|
|
|
251
304
|
// scripts/josh/command-suggest.ts
|
|
252
305
|
var MAX_SUGGESTION_DISTANCE = 3;
|
|
@@ -536,7 +589,7 @@ var LANE_COMMANDS = {
|
|
|
536
589
|
...LANE_ARGUMENTS,
|
|
537
590
|
description: "Block until any of the named in-flight lane children completes; prints which one finished",
|
|
538
591
|
category: "AI tools",
|
|
539
|
-
reference: ["<issue> [<issue>...]", "automation", ["processes"]],
|
|
592
|
+
reference: ["<issue> [<issue>...] [--owner <pid>]", "automation", ["files", "processes"]],
|
|
540
593
|
default_script_arguments: ["await"]
|
|
541
594
|
},
|
|
542
595
|
"lane:launch": {
|
|
@@ -1237,6 +1290,13 @@ var PROJECT_COMMANDS = {
|
|
|
1237
1290
|
["files", "git", "network", "processes"]
|
|
1238
1291
|
]
|
|
1239
1292
|
},
|
|
1293
|
+
"dogfood:commit": {
|
|
1294
|
+
script: "scripts/dogfood/dogfood-commit-cli.ts",
|
|
1295
|
+
description: "Make the first commit of a dogfood run's own kit-test-* project",
|
|
1296
|
+
category: "Project",
|
|
1297
|
+
reference: ["<dir>", "automation", ["files", "git"]],
|
|
1298
|
+
is_kit_only: true
|
|
1299
|
+
},
|
|
1240
1300
|
init: {
|
|
1241
1301
|
script: "scripts/init/init.ts",
|
|
1242
1302
|
description: "Initialize config in a new project",
|
|
@@ -1255,7 +1315,7 @@ var PROJECT_COMMANDS = {
|
|
|
1255
1315
|
},
|
|
1256
1316
|
"registry:migrate": {
|
|
1257
1317
|
script: "scripts/registry-migration/migrate.ts",
|
|
1258
|
-
description: "Migrate a
|
|
1318
|
+
description: "Migrate a project from GitHub Packages to public npm",
|
|
1259
1319
|
category: "Project",
|
|
1260
1320
|
reference: ["", "developer", ["files", "network", "processes"]]
|
|
1261
1321
|
},
|
|
@@ -1441,7 +1501,7 @@ var WORKFLOW_COMMANDS = {
|
|
|
1441
1501
|
script: "scripts/issue/measure-rerun-cli.ts",
|
|
1442
1502
|
description: "Re-run a merged issue\u2019s baseline command and print the before/after pair",
|
|
1443
1503
|
category: "Workflow",
|
|
1444
|
-
reference: ["<
|
|
1504
|
+
reference: ["<issue-number>", "automation", ["network", "processes", "files"]]
|
|
1445
1505
|
},
|
|
1446
1506
|
// A script rather than an `sh -c` chain, because it has a precondition to enforce: run inside a
|
|
1447
1507
|
// linked work tree it would hijack the default branch from every other one (joshuafolkken/kit#1535).
|
|
@@ -1700,7 +1760,6 @@ var repo_origin = {
|
|
|
1700
1760
|
};
|
|
1701
1761
|
|
|
1702
1762
|
// scripts/josh/run-github-prerequisite.ts
|
|
1703
|
-
import { execaSync as execaSync2 } from "execa";
|
|
1704
1763
|
var GITHUB_RUN_COMMANDS = /* @__PURE__ */ new Set([
|
|
1705
1764
|
"run:entry",
|
|
1706
1765
|
"run:prep",
|
|
@@ -1714,11 +1773,8 @@ function explanation(root, command) {
|
|
|
1714
1773
|
if (!existsSync3(path3.join(root, ".git"))) {
|
|
1715
1774
|
return `${command} requires Git and a GitHub origin. Run git init and add a GitHub origin first.`;
|
|
1716
1775
|
}
|
|
1717
|
-
const
|
|
1718
|
-
|
|
1719
|
-
reject: false
|
|
1720
|
-
});
|
|
1721
|
-
if (result.exitCode === 0 && repo_origin.parse_origin_url(result.stdout)) return void 0;
|
|
1776
|
+
const url = git_spawn_sync.origin_url(root);
|
|
1777
|
+
if (url !== void 0 && repo_origin.parse_origin_url(url)) return void 0;
|
|
1722
1778
|
return `${command} requires a GitHub origin. Add an origin pointing to GitHub first.`;
|
|
1723
1779
|
}
|
|
1724
1780
|
var run_github_prerequisite = { explanation };
|
|
@@ -1821,7 +1877,7 @@ function should_use_shell(executable) {
|
|
|
1821
1877
|
return process.platform === "win32" && executable !== process.execPath;
|
|
1822
1878
|
}
|
|
1823
1879
|
function spawn_script(tsx_executable, script_arguments) {
|
|
1824
|
-
const result =
|
|
1880
|
+
const result = execaSync2(tsx_executable, script_arguments, {
|
|
1825
1881
|
stdio: "inherit",
|
|
1826
1882
|
shell: should_use_shell(tsx_executable),
|
|
1827
1883
|
reject: false
|
|
@@ -1830,7 +1886,7 @@ function spawn_script(tsx_executable, script_arguments) {
|
|
|
1830
1886
|
}
|
|
1831
1887
|
function run_shell_command(shell, extra) {
|
|
1832
1888
|
const [executable = "", ...rest_arguments] = shell;
|
|
1833
|
-
const result =
|
|
1889
|
+
const result = execaSync2(executable, [...rest_arguments, ...extra], {
|
|
1834
1890
|
stdio: "inherit",
|
|
1835
1891
|
reject: false
|
|
1836
1892
|
});
|
package/dist/version/index.js
CHANGED
|
@@ -565,7 +565,13 @@ var agent_session_environment = {
|
|
|
565
565
|
function message_of(error) {
|
|
566
566
|
return error instanceof Error ? error.message : String(error);
|
|
567
567
|
}
|
|
568
|
-
var
|
|
568
|
+
var DEBUG_ENV_KEY = "JOSH_DEBUG";
|
|
569
|
+
function trace_swallowed(where, error) {
|
|
570
|
+
if ((process.env[DEBUG_ENV_KEY] ?? "").trim() === "") return;
|
|
571
|
+
process.stderr.write(`josh debug: ${where}: ${message_of(error)}
|
|
572
|
+
`);
|
|
573
|
+
}
|
|
574
|
+
var error_text = { message_of, trace_swallowed };
|
|
569
575
|
|
|
570
576
|
// scripts/gh/git-gh-exec.ts
|
|
571
577
|
import { execa as execa2, execaSync } from "execa";
|
|
@@ -1009,18 +1015,23 @@ function is_package_entry(line) {
|
|
|
1009
1015
|
function is_github_tarball_line(line) {
|
|
1010
1016
|
return line.trimStart().startsWith("tarball: https://npm.pkg.github.com/");
|
|
1011
1017
|
}
|
|
1012
|
-
function
|
|
1013
|
-
|
|
1018
|
+
function package_id(key) {
|
|
1019
|
+
const name = fix_gh_packages_logic.package_path_from_key(key);
|
|
1020
|
+
return `${name}@${fix_gh_packages_logic.package_version_from_key(key)}`;
|
|
1021
|
+
}
|
|
1022
|
+
function clean_scoped_line(line, id, integrities) {
|
|
1023
|
+
if (!id) return line;
|
|
1014
1024
|
if (is_github_tarball_line(line)) return void 0;
|
|
1015
1025
|
const cleaned = remove_flow_tarball(line);
|
|
1016
|
-
const pair = integrities.get(
|
|
1026
|
+
const pair = integrities.get(id);
|
|
1017
1027
|
if (pair === void 0) return cleaned;
|
|
1018
1028
|
return cleaned.split(`integrity: ${pair[0]}`).join(`integrity: ${pair[1]}`);
|
|
1019
1029
|
}
|
|
1020
|
-
function
|
|
1021
|
-
if (!is_package_entry(line)) return
|
|
1022
|
-
const prefix =
|
|
1023
|
-
|
|
1030
|
+
function next_scoped_id(line, id) {
|
|
1031
|
+
if (!is_package_entry(line)) return id;
|
|
1032
|
+
const prefix = ` '${SCOPE}/`;
|
|
1033
|
+
if (!line.startsWith(prefix)) return "";
|
|
1034
|
+
return package_id(line.slice(" '".length).split("'", 1)[0] ?? "");
|
|
1024
1035
|
}
|
|
1025
1036
|
function integrity_pair(old_integrity, npm_integrity) {
|
|
1026
1037
|
if (old_integrity === void 0 || npm_integrity === void 0) return void 0;
|
|
@@ -1029,24 +1040,24 @@ function integrity_pair(old_integrity, npm_integrity) {
|
|
|
1029
1040
|
function lock_integrities(lockfile, npm_integrities) {
|
|
1030
1041
|
const packages = fix_gh_packages_logic.parse_lockfile_packages(lockfile);
|
|
1031
1042
|
const pairs = /* @__PURE__ */ new Map();
|
|
1032
|
-
const
|
|
1033
|
-
for (const [key, entry] of
|
|
1034
|
-
const
|
|
1035
|
-
const pair = integrity_pair(entry.resolution?.integrity, npm_integrities.get(
|
|
1036
|
-
if (pair !== void 0) pairs.set(
|
|
1043
|
+
const scoped_entries = Object.entries(packages).filter(([key]) => key.startsWith(`${SCOPE}/`));
|
|
1044
|
+
for (const [key, entry] of scoped_entries) {
|
|
1045
|
+
const id = package_id(key);
|
|
1046
|
+
const pair = integrity_pair(entry.resolution?.integrity, npm_integrities.get(id));
|
|
1047
|
+
if (pair !== void 0) pairs.set(id, pair);
|
|
1037
1048
|
}
|
|
1038
1049
|
return pairs;
|
|
1039
1050
|
}
|
|
1040
1051
|
function push_if_defined(lines, cleaned) {
|
|
1041
1052
|
if (cleaned !== void 0) lines.push(cleaned);
|
|
1042
1053
|
}
|
|
1043
|
-
function
|
|
1044
|
-
let
|
|
1054
|
+
function rewrite_scoped_lockfile(lockfile, npm_integrities) {
|
|
1055
|
+
let id = "";
|
|
1045
1056
|
const lines = [];
|
|
1046
1057
|
const integrities = lock_integrities(lockfile, npm_integrities);
|
|
1047
1058
|
for (const line of lockfile.split("\n")) {
|
|
1048
|
-
|
|
1049
|
-
const cleaned =
|
|
1059
|
+
id = next_scoped_id(line, id);
|
|
1060
|
+
const cleaned = clean_scoped_line(line, id, integrities);
|
|
1050
1061
|
push_if_defined(lines, cleaned);
|
|
1051
1062
|
}
|
|
1052
1063
|
return lines.join("\n");
|
|
@@ -1076,7 +1087,7 @@ function previous_registry(project_npmrc, user_npmrc) {
|
|
|
1076
1087
|
}
|
|
1077
1088
|
function plan(project_npmrc, user_npmrc, lockfile) {
|
|
1078
1089
|
const packages = scoped_packages(lockfile);
|
|
1079
|
-
const blocked =
|
|
1090
|
+
const blocked = [];
|
|
1080
1091
|
if (has_duplicate_mapping(project_npmrc, user_npmrc)) blocked.push("duplicate registry mappings");
|
|
1081
1092
|
const unsupported = unsupported_registry(project_npmrc);
|
|
1082
1093
|
if (unsupported !== void 0) blocked.push(unsupported);
|
|
@@ -1088,7 +1099,7 @@ var migrate_logic = {
|
|
|
1088
1099
|
plan,
|
|
1089
1100
|
github_tarballs,
|
|
1090
1101
|
is_github_tarball,
|
|
1091
|
-
|
|
1102
|
+
rewrite_scoped_lockfile,
|
|
1092
1103
|
scoped_versions
|
|
1093
1104
|
};
|
|
1094
1105
|
|
|
@@ -1276,6 +1287,7 @@ var version_targets = {
|
|
|
1276
1287
|
var FAILURE_EXIT_CODE = 1;
|
|
1277
1288
|
var ALREADY_UP_TO_DATE = "Already up to date";
|
|
1278
1289
|
var NO_QUARANTINE_MINUTES2 = 0;
|
|
1290
|
+
var UPGRADE_TIMEOUT_MS = 6e5;
|
|
1279
1291
|
function read_release_hold(package_config, latest, versions) {
|
|
1280
1292
|
if (versions.every((version) => version === void 0 || version === latest)) return void 0;
|
|
1281
1293
|
const minimum_age_minutes = release_age.read_nearest_minimum_release_age(process.cwd());
|
|
@@ -1360,7 +1372,11 @@ function run_check(config) {
|
|
|
1360
1372
|
);
|
|
1361
1373
|
}
|
|
1362
1374
|
function run_upgrade_command(command) {
|
|
1363
|
-
const result = execaSync4("sh", ["-c", command], {
|
|
1375
|
+
const result = execaSync4("sh", ["-c", command], {
|
|
1376
|
+
stdio: "inherit",
|
|
1377
|
+
reject: false,
|
|
1378
|
+
timeout: UPGRADE_TIMEOUT_MS
|
|
1379
|
+
});
|
|
1364
1380
|
return result.exitCode ?? FAILURE_EXIT_CODE;
|
|
1365
1381
|
}
|
|
1366
1382
|
function run_all_upgrade_commands(commands) {
|
package/eslint/rules/unicorn.js
CHANGED
|
@@ -80,8 +80,9 @@ export const unicorn_rules = {
|
|
|
80
80
|
'unicorn/custom-error-definition': 'error',
|
|
81
81
|
// throw new Error()の形式を強制
|
|
82
82
|
'unicorn/throw-new-error': 'error',
|
|
83
|
-
//
|
|
84
|
-
|
|
83
|
+
// 空ファイルを禁止する。コメントだけのファイルは許可する: `sv create` の足場 `src/lib/index.ts` は
|
|
84
|
+
// コメント 1 行だけで、手を加えていないプロジェクトで lint が落ちてしまうため(#3069)
|
|
85
|
+
'unicorn/no-empty-file': ['error', { allowComments: true }],
|
|
85
86
|
// 静的なみずからのみのクラスを禁止
|
|
86
87
|
'unicorn/no-static-only-class': 'error',
|
|
87
88
|
// this別名を禁止(arrow functionを使うべき)
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.1136.0",
|
|
3
3
|
"name": "@joshuafolkken/kit",
|
|
4
4
|
"description": "Development toolkit for AI-assisted projects: formatting, AI assistant rules and a Git/GitHub Issue workflow for any repository, plus lint, type check, tests and hooks for Node projects",
|
|
5
5
|
"keywords": [
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"lefthook",
|
|
43
43
|
".claude/settings.json",
|
|
44
44
|
".claude/skills",
|
|
45
|
+
".claude/agents",
|
|
45
46
|
".claude/.claude-plugin",
|
|
46
47
|
".claude-plugin",
|
|
47
48
|
".codex",
|
|
@@ -59,6 +60,7 @@
|
|
|
59
60
|
".ncurc.json",
|
|
60
61
|
".prettierignore",
|
|
61
62
|
"pnpm-workspace.yaml",
|
|
63
|
+
".pnpmfile.mjs",
|
|
62
64
|
"tsconfig.sonar.json",
|
|
63
65
|
"playwright.config.ts",
|
|
64
66
|
"!**/*.test.ts",
|
|
@@ -71,6 +73,7 @@
|
|
|
71
73
|
"!scripts/time",
|
|
72
74
|
"!scripts/cost",
|
|
73
75
|
"!scripts/retrospective",
|
|
76
|
+
"!scripts/dogfood",
|
|
74
77
|
"!scripts/test/classify-isolation.ts",
|
|
75
78
|
"!scripts/test/http-fault-injection.ts",
|
|
76
79
|
"!scripts/test/josh-harness*.ts",
|
|
@@ -161,6 +164,7 @@
|
|
|
161
164
|
"peerDependencies": {
|
|
162
165
|
"@eslint/compat": "^2.1.1",
|
|
163
166
|
"@eslint/js": "^10.0.1",
|
|
167
|
+
"@ianvs/prettier-plugin-sort-imports": "^4.7.1",
|
|
164
168
|
"@playwright/test": ">=1.0.0",
|
|
165
169
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
166
170
|
"eslint": "^10.0.0",
|
|
@@ -171,6 +175,9 @@
|
|
|
171
175
|
"eslint-plugin-sonarjs": "^4.2.1",
|
|
172
176
|
"eslint-plugin-unicorn": "^76.0.0",
|
|
173
177
|
"globals": "^17.12.0",
|
|
178
|
+
"prettier": "^3.9.9",
|
|
179
|
+
"prettier-plugin-svelte": "^4.1.1",
|
|
180
|
+
"prettier-plugin-tailwindcss": "^0.8.1",
|
|
174
181
|
"typescript": "^6.0.3",
|
|
175
182
|
"typescript-eslint": "^8.70.1"
|
|
176
183
|
},
|
|
@@ -184,6 +191,9 @@
|
|
|
184
191
|
"@eslint/js": {
|
|
185
192
|
"optional": true
|
|
186
193
|
},
|
|
194
|
+
"@ianvs/prettier-plugin-sort-imports": {
|
|
195
|
+
"optional": true
|
|
196
|
+
},
|
|
187
197
|
"@stylistic/eslint-plugin": {
|
|
188
198
|
"optional": true
|
|
189
199
|
},
|
|
@@ -211,6 +221,15 @@
|
|
|
211
221
|
"globals": {
|
|
212
222
|
"optional": true
|
|
213
223
|
},
|
|
224
|
+
"prettier": {
|
|
225
|
+
"optional": true
|
|
226
|
+
},
|
|
227
|
+
"prettier-plugin-svelte": {
|
|
228
|
+
"optional": true
|
|
229
|
+
},
|
|
230
|
+
"prettier-plugin-tailwindcss": {
|
|
231
|
+
"optional": true
|
|
232
|
+
},
|
|
214
233
|
"typescript": {
|
|
215
234
|
"optional": true
|
|
216
235
|
},
|
|
@@ -224,13 +243,13 @@
|
|
|
224
243
|
"@eslint/js": "^10.0.1",
|
|
225
244
|
"@ianvs/prettier-plugin-sort-imports": "^4.7.1",
|
|
226
245
|
"@playwright/test": "^1.63.0",
|
|
227
|
-
"@secretlint/secretlint-rule-preset-recommend": "^13.0.
|
|
246
|
+
"@secretlint/secretlint-rule-preset-recommend": "^13.0.7",
|
|
228
247
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
229
248
|
"@types/node": "^26.6.4",
|
|
230
249
|
"@types/semver": "^7.8.0",
|
|
231
250
|
"cspell": "^10.3.6",
|
|
232
251
|
"esbuild": "^0.28.2",
|
|
233
|
-
"eslint": "^10.
|
|
252
|
+
"eslint": "^10.12.0",
|
|
234
253
|
"eslint-config-prettier": "^10.1.8",
|
|
235
254
|
"eslint-import-resolver-typescript": "^4.4.5",
|
|
236
255
|
"eslint-plugin-import-x": "^4.17.1",
|
|
@@ -245,7 +264,7 @@
|
|
|
245
264
|
"prettier-plugin-tailwindcss": "^0.8.1",
|
|
246
265
|
"rollup": "^4.64.0",
|
|
247
266
|
"rollup-plugin-dts": "^6.5.1",
|
|
248
|
-
"secretlint": "^13.0.
|
|
267
|
+
"secretlint": "^13.0.7",
|
|
249
268
|
"typescript": "^6.0.3",
|
|
250
269
|
"typescript-eslint": "^8.71.0",
|
|
251
270
|
"vitest": "^5.0.3"
|
|
@@ -256,7 +275,6 @@
|
|
|
256
275
|
"jsonc-parser": "^3.3.1",
|
|
257
276
|
"ora": "^9.4.1",
|
|
258
277
|
"semver": "^7.8.5",
|
|
259
|
-
"strip-json-comments": "^5.0.3",
|
|
260
278
|
"tsx": "^4.23.15",
|
|
261
279
|
"zod": "^4.6.5"
|
|
262
280
|
},
|
package/pnpm-workspace.yaml
CHANGED
|
@@ -28,11 +28,9 @@ minimumReleaseAgeExclude:
|
|
|
28
28
|
|
|
29
29
|
overrides:
|
|
30
30
|
svelte: ^5.55.7
|
|
31
|
-
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
31
|
+
# An indirect dep a within-range re-resolution could not lift past its parents' pins, floored at the
|
|
32
|
+
# smallest release clearing its OSV advisory (joshuafolkken/kit#2200; user-approved 2026-09-21 to
|
|
33
|
+
# override indirect packages). A caret so `josh latest`'s re-resolution keeps it current within the
|
|
34
|
+
# major without reintroducing the advisory. The devalue, postcss and nanoid floors were removed once
|
|
35
|
+
# their parents' ranges exceeded them (joshuafolkken/kit#3091).
|
|
36
36
|
vite: ^8.0.16 # OSV — vite 8.0.8 → 8.0.16
|
|
37
|
-
postcss: ^8.5.23 # OSV — postcss 8.5.16 → 8.5.23
|
|
38
|
-
nanoid: ^3.3.18 # OSV — nanoid 3.3.15 → 3.3.18
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# ワークフロー用語集
|
|
2
|
+
|
|
3
|
+
**これは定義集であり、規則を定める場所ではない。** 各語は 1〜2 行の定義と、その語の本文がある単一ソースへのポインタだけを持つ。手順・条件・数値は指し先が持ち、ここでは言い換えない — 言い換えた行は指し先より先に古くなる(joshuafolkken/kit#3080)。
|
|
4
|
+
|
|
5
|
+
`scripts/document/workflow-glossary.test.ts` が、下の主要語が定義されていることと、各ポインタが実在する節に解決することを検査する。
|
|
6
|
+
|
|
7
|
+
- **lane** — `backlogrun` が子 Issue を並行実行するための、専用ブランチ・`.env`・ポートを持つ git worktree。実装・ゲート・レビューは並行し、マージは直列。→ `.claude/skills/workflow-commands/backlogrun-lanes.md` → "Lanes — running more than one child at a time"
|
|
8
|
+
- **cut** — 実行中のプロセスを意図して終わらせ、新しいプロセスが同じ作業を引き継ぐ境界。レーン子のゲート前の cut と、`backlogrun` のセッション cut がある。→ `.claude/skills/workflow-commands/pre-gate-cut.md` → "The pre-gate cut"、`.claude/skills/workflow-commands/backlogrun-progress.md` → "The hand-off"
|
|
9
|
+
- **hold** — 1 つの作業ツリーを 1 つのランが占有しているという記録。`pnpm josh run:hold` が取り、`pnpm josh run:release` が外す。→ `.claude/skills/workflow-commands/working-tree-hold.md` → "The working-tree hold"
|
|
10
|
+
- **park** — `backlogrun` が自分で決められない子を `needs-decision` で止め、バッチ全体は止めずに次の子へ進むこと。→ `.claude/skills/workflow-commands/backlogrun-park.md` → "park and continue"
|
|
11
|
+
- **point of use** — 文書を入口ではなく、その文書に従うべき操作と同じターンで、その操作の直前に読むこと。→ `.claude/skills/workflow-commands/SKILL.md` → "Four documents are read at the point of use, not at the entry"
|
|
12
|
+
- **entry read** — コマンド起動時に読む文書の集合。`pnpm josh read:set` がその集合と費用を答える。→ `.claude/skills/workflow-commands/SKILL.md` → "Which file to read"
|
|
13
|
+
- **oracle** — 機械的に読める入力だけから規則の答えを計算するコマンド。一覧は `pnpm josh oracle:list`。→ `prompts/collaboration-workflow/residency.md` → "第 0 問"
|
|
14
|
+
- **interrupt** — WIP 上限を超えても起票できる、3 条件で決まる発見。別パッケージ起因の上流起票(割り込み Issue)とは別の区分。→ `prompts/collaboration-workflow/wip-cap.md` → "割り込み起票"、`prompts/collaboration-workflow/upstream-interrupt.md` → "別パッケージ起因の問題は割り込み Issue で対応する"
|
|
15
|
+
- **Tier** — 判断点の 3 区分。A は可逆で自分で決める、B は拮抗していて人に聞く、C は不可逆・共有状態で明示指示が要る。→ `CLAUDE.md` → "Decision autonomy"、`prompts/collaboration-workflow/operating-rules.md` → "意思決定の自律ポリシー"
|
|
16
|
+
- **carry** — `backlogrun` の 1 回の起動の予算と進捗を、セッション cut をまたいで引き継ぐ記録(`pnpm josh run:carry`)。→ `.claude/skills/workflow-commands/backlogrun-steps.md` → "The session cut is inside the invocation"
|
|
17
|
+
- **wave** — エピックの子をまとめて並行実行する組。仕組みではなく、依存宣言で表す形。→ `.claude/skills/epic-commands/SKILL.md` → "Execution waves"
|
|
@@ -76,7 +76,7 @@ Issue には次の要素を必ず含める。
|
|
|
76
76
|
- **互換性を壊す変更は影響を本文で宣言する。** 既存の利用者、API、設定の契約を変える場合は、`## 背景` の直下に `- 互換性: 破壊的変更` を書き、廃止対象と影響を説明する。移行措置や事前案内があっても破壊的変更なら宣言する。この宣言があれば `pnpm josh issue:file` が `breaking-change` ラベルを同じ作成リクエストに付ける。互換性を保つ変更には付けない。影響が曖昧なら起票文案で対象の利用者と契約を明確にしてから分類する
|
|
77
77
|
- **本文が宣言する分類ラベルは `pnpm josh issue:file` がすべて起票時に付ける。** `bug`、`enhancement`、`breaking-change` は組み合わせて付くことがある。`depth`・`route` などのラベルと併せて 1 回の作成リクエストで付け、宣言が無いとき(`issue:lint` の `labels: none`)は分類ラベルを付けない。Issue が `enhancement` と `breaking-change` の両方を持つとき、PR のリリース分類は `breaking-change` 一つにする。Issue の目的の分類と PR のリリース分類を区別する
|
|
78
78
|
- **`## 発火点`** には、その規則が破れる瞬間に最初に呼ばれるツールコール名を 1 つ書く。名前は `prompts/collaboration-workflow/rule-delivery.md` の配送表に載る、フックで配送可能なツール(`Bash` / `Edit` / `Read` / `Write` / `AskUserQuestion`)と突き合わせる。**表に無い名前**(そもそもツールコール名でない)と**不一致**(既知のツールだが配送できない)は区別して印字され、joshuafolkken/kit#2201 の「規則は正しいが名指ししたコールが実際に破れるコールの 1 つ後ろ」を起票時に検出する
|
|
79
|
-
- **`## ベースライン`** は **「コマンド + 値」** で書く。``- `<測定コマンド>` → <現在の値>`` の形に限り、自然文だけの測定説明は受け付けない(再実行できないため)。マージ後に `pnpm josh measure:rerun`
|
|
79
|
+
- **`## ベースライン`** は **「コマンド + 値」** で書く。``- `<測定コマンド>` → <現在の値>`` の形に限り、自然文だけの測定説明は受け付けない(再実行できないため)。マージ後に `pnpm josh measure:rerun <N>` が同じコマンドをやり直し(本文は shell として実行されるため、作者が `OWNER` / `MEMBER` / `COLLABORATOR` の Issue に限る)、**before / after の対**を印字する。値が動かなかったとき、反証された前提として `docs/maintainers/observations/` の、その時点のブランチが指す Issue のファイルに 1 行追記される(既存の append-only 台帳を使い、別の台帳は作らない)
|
|
80
80
|
- **`## 再現`** は **「コマンド + 実際の出力」** で書く。コマンドを backtick、出力をフェンス(``` または ~~~)で囲む。自然文の「確認した」は再実行できないため受け付けない(`## ベースライン` と同じ理由)。読みだけの起票を起票時に弾くためである
|
|
81
81
|
- **検査は `pnpm josh issue:lint <path>` が行う。** 対象判定・3 見出しの有無・発火点の配送可否・ベースラインが「コマンド + 値」か・再現が「コマンド + 実際の出力」かと、起票時に必要な分類ラベルを、起票前の本文ファイルからまとめて答える(`pnpm josh issue:file` は起票前に同じ検査を行い、問題があれば起票しない)
|
|
82
82
|
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
PR マージ・ブランチ削除・force push・共有ブランチへの push・外部通知の追加送信・リポジトリ設定の変更など、**共有状態に影響する操作はその場でユーザーに明示指示されたものだけ実行する**。
|
|
29
29
|
|
|
30
|
-
- `fullrun` の auto-merge
|
|
30
|
+
- `fullrun` と `backlogrun` の auto-merge は、それぞれの指示自体に含まれるため許可される(本文は [`followup.md`](../../.claude/skills/workflow-commands/followup.md)、`backlogrun` の子への継承は [`backlogrun-child.md`](../../.claude/skills/workflow-commands/backlogrun-child.md))。`prrun` はマージを認可しない。それ以外の状況で勝手にマージしてはならない
|
|
31
31
|
- `kickoff` / `pnpm josh followup` 単独実行は文書化されたスコープで終了する。PR が OPEN のまま完了したら状態を報告して停止する
|
|
32
32
|
- 「チェックが全部 green だから次のステップに進む」は承認ではない
|
|
33
33
|
- **`gh pr merge` の直接実行は kit 配布の `.claude/settings.json` の `permissions.deny` で機械的に遮断されている。** パターンの一覧はそのファイルが一次情報であり、ここでは書き写さない。 `fullrun` の auto-merge は `pnpm josh followup` が node スクリプト内部から gh を起動するため影響を受けない — Bash マッチャに見えるのは `pnpm josh …` だけである。**ただし deny は実装であって規則ではない** — パターンが取りこぼす綴りを禁じているのは本節の規則のほうである
|
|
@@ -72,3 +72,12 @@
|
|
|
72
72
|
- **導線文書に規則を書き戻さない。** そこに書かれた規則は、次の改訂で更新し忘れる 4 つ目の置き場になる
|
|
73
73
|
- `scripts/document/ai-document-pointers.test.ts` が機械的に守る。導線文書に規則本体が再出現した場合、導線の一文が消えた場合、`CLAUDE.md` が単一ソースであることの記述が消えた場合に落ちる
|
|
74
74
|
- 経緯は `docs/maintainers/principles-rationale.md` → "Why AGENTS and GEMINI are pointers"、`@CLAUDE.md` 行と他ツールでの未検証は `docs/maintainers/principles-rationale.md` → "The include line, and what has not been verified"
|
|
75
|
+
|
|
76
|
+
### Claude Code 以外のエージェントでの読み替え
|
|
77
|
+
|
|
78
|
+
`CLAUDE.md` は Claude Code 向けに書かれており、その機能を名指しする。Codex・Gemini CLI など別のエージェントは次のように読み替える。導線文書が持つのはツール固有の 1 行だけで、共通の読み替えはこの節にしか無い(joshuafolkken/kit#3079)。
|
|
79
|
+
|
|
80
|
+
- **フック**: フックが走らない、または出力が見えないツールでは、フックが届ける規則を自分で適用する。その一覧は手書きせず、[`rule-delivery.md`](./rule-delivery.md) →「配送されている規則」の表を正とする — 表の各行が、そのツールでは自分で守る規則である。表の外でフックが担う 3 つも同じく自分で行う — 最初の実行時コード編集の前に Step 0 の作業サマリを提示する、編集ごとの整形フックに頼らず編集後に `pnpm josh lint:related` と `pnpm josh cspell:dot` を走らせる、`JOSH_SESSION_LANG` は注入を待たずに `.env` から解決する。フックの全体は `.claude/settings.json` の `hooks` が正である
|
|
81
|
+
- **Skill・`/verify-ui`・`/code-review`**: `CLAUDE.md` が skill のロードやサブエージェントでの実行を指示する箇所では、その skill の `SKILL.md` を読み、自分のセッションで従う
|
|
82
|
+
- **`.claude/settings.json` の deny list** は効かない。それが裏付ける規則 — 指示なしのコミット・マージ・ステージングその他の共有状態変更をしない — はそのまま拘束する
|
|
83
|
+
- **`AskUserQuestion`** は、ユーザーに平文で尋ねることを指す
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
| 引き金つき配送 — 規則を効く瞬間に届ける | [`rule-delivery.md`](./collaboration-workflow/rule-delivery.md) |
|
|
30
30
|
| コマンド出力が文脈へ持ち込む量の上限 | [`output-bounds.md`](./collaboration-workflow/output-bounds.md) |
|
|
31
31
|
| 運用ルール | [`operating-rules.md`](./collaboration-workflow/operating-rules.md) |
|
|
32
|
+
| 用語集 — lane・cut・hold・park などの定義と単一ソース | [`glossary.md`](./collaboration-workflow/glossary.md) |
|
|
32
33
|
|
|
33
34
|
**どの 1 本を開けばよいかを決めるのに必要なのは、この索引だけである。** バイト数はここに書かない — 手で保守した数字は本文より先に古くなり、古い数字は無いより悪い。実サイズは `ls -l prompts/collaboration-workflow/` が答える。
|
|
34
35
|
|
|
@@ -18,10 +18,11 @@ import { backlog_stalled } from './backlog-stalled'
|
|
|
18
18
|
//
|
|
19
19
|
// **"New" is measured against the watcher's own start**, so one issue wakes the parent once: the next
|
|
20
20
|
// `--wait` the parent starts takes the pool as it stands then — the woken issue included, dispatched or
|
|
21
|
-
// not — as its baseline. A reading that fails is not an arrival; the probe says nothing and
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
21
|
+
// not — as its baseline. A reading that fails is not an arrival; the probe says nothing and reads again
|
|
22
|
+
// a minute later. A baseline that cannot be read is never read as empty — an empty one would wake the
|
|
23
|
+
// parent for the whole pool — but it is not given up on either: the scheduled report no longer ends the
|
|
24
|
+
// wait (joshuafolkken/kit#3102), so an inert probe would leave the parent without a wake until `--hours`. The
|
|
25
|
+
// probe reads the baseline again each minute until one answers.
|
|
25
26
|
//
|
|
26
27
|
// **Every read is bounded.** The probe is awaited inside the watcher's tick loop, so a `gh` call that
|
|
27
28
|
// hangs would otherwise freeze the loop — its `--hours` bound, its liveness ping and the exit that is
|
|
@@ -116,19 +117,40 @@ async function never_arrives(): Promise<boolean> {
|
|
|
116
117
|
|
|
117
118
|
const INERT: ArrivalProbe = { has_arrived: never_arrives }
|
|
118
119
|
|
|
119
|
-
//
|
|
120
|
+
// A probe spent on the baseline reports no arrival, whether or not the baseline answered.
|
|
121
|
+
async function retry_baseline(
|
|
122
|
+
answered: Array<ReadonlySet<string>>,
|
|
123
|
+
ports: ReadyPorts,
|
|
124
|
+
): Promise<boolean> {
|
|
125
|
+
const late = await read_baseline(ports)
|
|
126
|
+
|
|
127
|
+
if (late !== undefined) answered.push(late)
|
|
128
|
+
|
|
129
|
+
return false
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// The next-probe instant is set before any read is awaited. A baseline that did not answer is read again
|
|
133
|
+
// at the next probe instead of the reading, and the first one that answers is the baseline from then on
|
|
134
|
+
// — never an arrival itself, since it is the pool as it stands.
|
|
120
135
|
function probe_of(
|
|
121
|
-
|
|
136
|
+
initial: ReadonlySet<string> | undefined,
|
|
122
137
|
first_ms: number,
|
|
123
138
|
ports: ReadyPorts,
|
|
124
139
|
): ArrivalProbe {
|
|
125
140
|
let next_ms = first_ms
|
|
141
|
+
// At most one entry, held in a list so the baseline that answers after an await is added rather than
|
|
142
|
+
// reassigned over the value read before it.
|
|
143
|
+
const answered: Array<ReadonlySet<string>> = initial === undefined ? [] : [initial]
|
|
126
144
|
|
|
127
145
|
async function has_arrived(now_ms: number): Promise<boolean> {
|
|
128
146
|
if (now_ms < next_ms) return false
|
|
129
147
|
|
|
130
148
|
next_ms = now_ms + PROBE_INTERVAL_MS
|
|
131
149
|
|
|
150
|
+
const [baseline] = answered
|
|
151
|
+
|
|
152
|
+
if (baseline === undefined) return await retry_baseline(answered, ports)
|
|
153
|
+
|
|
132
154
|
const reading = await read_reading(ports)
|
|
133
155
|
|
|
134
156
|
return reading !== undefined && arrivals(baseline, reading).length > NONE
|
|
@@ -146,12 +168,10 @@ async function start(
|
|
|
146
168
|
): Promise<ArrivalProbe> {
|
|
147
169
|
if (!(await is_parent_safely(is_parent))) return INERT
|
|
148
170
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return baseline === undefined ? INERT : probe_of(baseline, now_ms + PROBE_INTERVAL_MS, ports)
|
|
171
|
+
return probe_of(await read_baseline(ports), now_ms + PROBE_INTERVAL_MS, ports)
|
|
152
172
|
}
|
|
153
173
|
|
|
154
|
-
const backlog_arrival = {
|
|
174
|
+
const backlog_arrival = { PROBE_INTERVAL_MS, answered_issues, arrivals, start }
|
|
155
175
|
|
|
156
176
|
export type { ArrivalProbe }
|
|
157
177
|
export { backlog_arrival }
|