@joshuafolkken/kit 1.1453.0 → 1.1471.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/skills/dependency-update/SKILL.md +26 -55
- package/.claude/skills/epic-commands/SKILL.md +87 -148
- package/.claude/skills/epic-commands/epic-bundle.md +45 -77
- package/.claude/skills/epic-commands/execution-waves.md +44 -81
- package/.claude/skills/verify-ui/SKILL.md +25 -50
- package/.claude/skills/workflow-commands/background-commands.md +36 -47
- package/.claude/skills/workflow-commands/backlogrun-child.md +72 -85
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +91 -121
- package/.claude/skills/workflow-commands/backlogrun-park.md +73 -117
- package/.claude/skills/workflow-commands/backlogrun-progress.md +7 -9
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +11 -20
- package/.claude/skills/workflow-commands/backlogrun-steps.md +43 -52
- package/.claude/skills/workflow-commands/chain-rule.md +24 -34
- package/.claude/skills/workflow-commands/followup.md +57 -76
- package/.claude/skills/workflow-commands/halfrun.md +2 -1
- package/.claude/skills/workflow-commands/issue-comments.md +43 -60
- package/.claude/skills/workflow-commands/kickoff.md +65 -74
- package/.claude/skills/workflow-commands/observation-filing.md +62 -107
- package/.claude/skills/workflow-commands/observation-ledger.md +56 -111
- package/.claude/skills/workflow-commands/pre-gate-cut.md +89 -138
- package/.claude/skills/workflow-commands/prerequisite.md +10 -15
- package/.claude/skills/workflow-commands/progress-watcher.md +21 -26
- package/.claude/skills/workflow-commands/prrun.md +2 -1
- package/.claude/skills/workflow-commands/retrospective.md +31 -50
- package/.claude/skills/workflow-commands/split-assessment.md +34 -58
- package/.claude/skills/workflow-commands/working-tree-hold.md +54 -71
- package/CLAUDE.md +7 -6
- package/README.md +2 -9
- package/dist/CLAUDE.md +7 -6
- package/dist/hooks/batch-guard.js +6 -6
- package/dist/hooks/{chunk-Y3GKIKGW.js → chunk-43ZHT22P.js} +31 -15
- package/dist/hooks/{chunk-MBJYQPEK.js → chunk-AS74OU3D.js} +24 -8
- package/dist/hooks/{chunk-3C4XRYG6.js → chunk-E7OIKX5Z.js} +17 -12
- package/dist/hooks/{chunk-Z4XI7CZS.js → chunk-EUMACUK2.js} +18 -12
- package/dist/hooks/{chunk-NO4AALP5.js → chunk-H5HVWYXK.js} +4 -4
- package/dist/hooks/{chunk-5C7L6FRC.js → chunk-IIGFYXKC.js} +346 -241
- package/dist/hooks/{chunk-W5ZKGTSY.js → chunk-J47HU5H5.js} +14 -3
- package/dist/hooks/{chunk-OLMO72ON.js → chunk-K4EOONYM.js} +1 -1
- package/dist/hooks/{chunk-LBFYEOXJ.js → chunk-K4LMBQC2.js} +4 -4
- package/dist/hooks/{chunk-D3NJXN5M.js → chunk-KC5AK2GF.js} +8 -6
- package/dist/hooks/chunk-SHGPANFB.js +56 -0
- package/dist/hooks/{chunk-EF5GQ6WS.js → chunk-YHBZAJSV.js} +3 -3
- package/dist/hooks/{chunk-SHYUQOIS.js → chunk-YYPI7SJZ.js} +5 -5
- package/dist/hooks/codex-hook-adapter.js +13 -13
- package/dist/hooks/duplicate-read-guard.js +7 -7
- package/dist/hooks/format-edited.js +3 -3
- package/dist/hooks/inputs.json +251 -247
- package/dist/hooks/investigation-guard.js +7 -7
- package/dist/hooks/pretool-guard.js +12 -12
- package/dist/hooks/session-lang.js +6 -5
- package/dist/hooks/stop-guard.js +75 -18
- package/dist/josh.js +6 -7
- package/dist/managed-marker/index.js +1 -2
- package/dist/version/index.js +15 -12
- package/eslint/base.js +2 -1
- package/eslint/rules/unicorn.js +16 -0
- package/package.json +3 -3
- package/prompts/coding-standards.md +12 -22
- package/prompts/collaboration-workflow/file-edits.md +26 -44
- package/prompts/collaboration-workflow/gh-rest.md +20 -36
- package/prompts/collaboration-workflow/glossary.md +5 -7
- package/prompts/collaboration-workflow/issue-citation.md +7 -13
- package/prompts/collaboration-workflow/issue-template.md +29 -29
- package/prompts/collaboration-workflow/operating-rules.md +35 -44
- package/prompts/collaboration-workflow/output-bounds.md +15 -15
- package/prompts/collaboration-workflow/overview.md +14 -19
- package/prompts/collaboration-workflow/plan-comment.md +13 -13
- package/prompts/collaboration-workflow/principles.md +50 -53
- package/prompts/collaboration-workflow/proposal-request.md +1 -9
- package/prompts/collaboration-workflow/report-format.md +32 -49
- package/prompts/collaboration-workflow/residency.md +10 -10
- package/prompts/collaboration-workflow/rule-delivery.md +9 -9
- package/prompts/collaboration-workflow/shell-body.md +11 -21
- package/prompts/collaboration-workflow/turn-batching.md +8 -14
- package/prompts/collaboration-workflow/upstream-interrupt.md +26 -34
- package/prompts/collaboration-workflow/wip-cap.md +24 -30
- package/prompts/collaboration-workflow.md +24 -25
- package/prompts/refactoring.md +33 -43
- package/prompts/review-rubric.md +84 -129
- package/prompts/review.md +111 -141
- package/prompts/sonar-hotspot-handling.md +22 -50
- package/prompts/testing-guide.md +48 -99
- package/scripts/adopt/adopt-toolkits.ts +2 -4
- package/scripts/agent/agent-exit-record.ts +23 -1
- package/scripts/agent/codex-agent-argv.ts +7 -2
- package/scripts/backlog/backlog-budget-cli.ts +1 -2
- package/scripts/backlog/backlog-drive-carried.ts +26 -0
- package/scripts/backlog/backlog-drive-cli.ts +10 -5
- package/scripts/backlog/backlog-drive-named.ts +2 -4
- package/scripts/backlog/backlog-drive-restore.ts +19 -1
- package/scripts/backlog/backlog-drive-seats.ts +27 -0
- package/scripts/backlog/backlog-drive.ts +11 -6
- package/scripts/backlog/backlog-ready.ts +13 -6
- package/scripts/behavior/behavior-rules.ts +3 -2
- package/scripts/cost-runtime/codex-usage.ts +4 -2
- package/scripts/cost-runtime/cost-cli.ts +1 -2
- package/scripts/delegation/investigation-guard.ts +1 -1
- package/scripts/delegation/investigation-reads.ts +1 -1
- package/scripts/discovery/repo-discovery.ts +4 -2
- package/scripts/discovery/repo-origin.ts +2 -4
- package/scripts/doctor/doctor-logic.ts +6 -3
- package/scripts/document/document-byte-budget.ts +27 -27
- package/scripts/document/document-byte-check.ts +1 -2
- package/scripts/document/entry-read-budget.ts +2 -2
- package/scripts/epic/epic-audit-rationale.ts +8 -2
- package/scripts/epic/epic-bundle-cli.ts +1 -2
- package/scripts/epic/epic-chains.ts +6 -2
- package/scripts/epic/epic-close-comment.ts +1 -2
- package/scripts/gate/verification-gate.ts +7 -2
- package/scripts/gh/git-pr-ai-review.ts +12 -1
- package/scripts/gh/git-pr-confirmation.ts +11 -7
- package/scripts/gh/git-pr.ts +6 -2
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +16 -9
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/hooks/format-edited-file.ts +10 -4
- package/scripts/hooks/pre-push-unit.ts +15 -4
- package/scripts/hooks/pretool-guard.ts +23 -29
- package/scripts/hooks/step-zero-notice.ts +3 -2
- package/scripts/init/hook-command-rewrite.ts +6 -2
- package/scripts/init/init-logic-deploy-vps.ts +4 -2
- package/scripts/issue/behavior-change-lint.ts +12 -6
- package/scripts/issue/issue-scout-cli.ts +3 -2
- package/scripts/josh/file-map-stamp.ts +1 -3
- package/scripts/josh/hook-decision.ts +17 -2
- package/scripts/josh/josh-commands-workflow.ts +1 -1
- package/scripts/lane/lane-await.ts +3 -2
- package/scripts/lane/lane-child-invocation.ts +14 -1
- package/scripts/lane/lane-guard-policy.ts +4 -4
- package/scripts/lane/lane-ledger.ts +9 -0
- package/scripts/lane/lane-load.ts +9 -2
- package/scripts/lane/lane-measure-cli.ts +2 -0
- package/scripts/lane/lane-parked.ts +18 -0
- package/scripts/lane/lane-process-load.ts +125 -0
- package/scripts/lane/lane-process-stats.ts +93 -0
- package/scripts/lane/lane-registry.ts +8 -3
- package/scripts/lane/lane-session-broker.ts +29 -5
- package/scripts/lane/lane-spent.ts +14 -3
- package/scripts/lane/lane-stats.ts +1 -0
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/confirmation-options.ts +59 -0
- package/scripts/notify/notify-opt-in.ts +33 -0
- package/scripts/notify/telegram-notify.ts +25 -8
- package/scripts/notify/telegram-test-logic.ts +33 -1
- package/scripts/notify/telegram-test.ts +4 -2
- package/scripts/overrides/lockfile-overrides.ts +1 -3
- package/scripts/propagate/propagate.ts +1 -2
- package/scripts/release/release-progress.ts +3 -2
- package/scripts/report/report-lint.ts +7 -4
- package/scripts/review/review-record-cli.ts +6 -2
- package/scripts/rules/destructive-command.ts +6 -9
- package/scripts/rules/direct-filing.ts +3 -7
- package/scripts/rules/early-heartbeat.ts +7 -18
- package/scripts/rules/file-body.ts +6 -13
- package/scripts/rules/filing-cap.ts +3 -6
- package/scripts/rules/git-force.ts +5 -9
- package/scripts/rules/implementation-cut.ts +37 -35
- package/scripts/rules/index-guard.ts +4 -7
- package/scripts/rules/issue-comments.ts +5 -15
- package/scripts/rules/josh-git-bare.ts +3 -6
- package/scripts/rules/lane-background.ts +10 -21
- package/scripts/rules/lane-carry-conflict.ts +7 -17
- package/scripts/rules/lane-interactive-ask.ts +6 -11
- package/scripts/rules/lane-park.ts +5 -13
- package/scripts/rules/lane-split-park.ts +2 -7
- package/scripts/rules/lane-switch-main.ts +9 -12
- package/scripts/rules/oracle-consulted.ts +4 -5
- package/scripts/rules/piped-verification.ts +81 -31
- package/scripts/rules/poll-loop.ts +7 -17
- package/scripts/rules/pre-gate-cut.ts +7 -21
- package/scripts/rules/prior-comment-read.ts +7 -5
- package/scripts/rules/protected-files.ts +5 -9
- package/scripts/rules/raw-field-body.ts +3 -7
- package/scripts/rules/rule-body-guard.ts +4 -11
- package/scripts/rules/run-tail-rule.ts +6 -22
- package/scripts/rules/shell-body-trigger.ts +7 -8
- package/scripts/rules/shell-segments.ts +7 -0
- package/scripts/rules/stop-rules.ts +17 -29
- package/scripts/rules/test-declared-commit.ts +4 -10
- package/scripts/rules/third-party-write.ts +5 -10
- package/scripts/rules/worktree-guard.ts +5 -12
- package/scripts/run/board/run-board-github.ts +11 -3
- package/scripts/run/board/run-board-idle.ts +31 -0
- package/scripts/run/board/run-board-read.ts +9 -12
- package/scripts/run/board/run-board-reason.ts +7 -3
- package/scripts/run/board/run-board-state.ts +4 -0
- package/scripts/run/board/run-board-status.ts +18 -3
- package/scripts/run/board/run-board-thanks.ts +7 -2
- package/scripts/run/board/run-board-tick.ts +32 -7
- package/scripts/run/carry/run-carry-args.ts +1 -3
- package/scripts/run/carry/run-carry-conversation.ts +7 -2
- package/scripts/run/cut/run-cut-cli.ts +15 -20
- package/scripts/run/cut/run-cut-decline.ts +72 -0
- package/scripts/run/cut/run-cut-ready.ts +74 -0
- package/scripts/run/cut/run-cut-report.ts +13 -0
- package/scripts/run/cut/run-cut.ts +10 -1
- package/scripts/run/entry/run-entry-stop.ts +6 -3
- package/scripts/run/hold/run-hold-cli.ts +14 -3
- package/scripts/run/hold/run-hold.ts +6 -3
- package/scripts/run/merge/run-merge-cli.ts +30 -7
- package/scripts/run/merge/run-merge-ship.ts +59 -1
- package/scripts/run/merge/run-merge.ts +3 -2
- package/scripts/run/run-ending.ts +31 -3
- package/scripts/run/run-parent-cut-hook.ts +5 -10
- package/scripts/run/run-preflight.ts +1 -2
- package/scripts/run/run-stop-notify.ts +3 -2
- package/scripts/run/run-watcher-guard.ts +6 -3
- package/scripts/run/ship/run-ship-review-steps.ts +13 -4
- package/scripts/run/ship/run-ship-review.ts +15 -2
- package/scripts/run/tidy/run-tidy-cli.ts +3 -3
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -2
- package/scripts/safe-chain/project-config.ts +7 -2
- package/scripts/sync/sync-hook-safety.ts +8 -2
- package/scripts/test/unit-worker-share.ts +3 -2
- package/scripts/time-runtime/time-batch-guard.ts +3 -3
- package/scripts/time-runtime/time-hook-transcript.ts +3 -2
- package/scripts/time-runtime/time-shell.ts +10 -0
- package/scripts/version/effective-upstream.ts +3 -4
- package/scripts/version/kit-version-config.ts +8 -2
- package/scripts/version/latest-corepack.ts +1 -2
- package/scripts/version/release-hold.ts +11 -4
- package/scripts/version/version-commands.ts +12 -4
- package/dist/hooks/chunk-UT7YC3N2.js +0 -56
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import {
|
|
3
3
|
pretool_guard
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-IIGFYXKC.js";
|
|
5
|
+
import "./chunk-YYPI7SJZ.js";
|
|
6
|
+
import "./chunk-43ZHT22P.js";
|
|
7
7
|
import "./chunk-IX6TTTI6.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-EUMACUK2.js";
|
|
9
9
|
import "./chunk-CDY4NFQG.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-YHBZAJSV.js";
|
|
11
|
+
import "./chunk-K4LMBQC2.js";
|
|
12
|
+
import "./chunk-H5HVWYXK.js";
|
|
13
|
+
import "./chunk-SHGPANFB.js";
|
|
14
14
|
import {
|
|
15
15
|
hook_decision
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-J47HU5H5.js";
|
|
17
|
+
import "./chunk-AS74OU3D.js";
|
|
18
|
+
import "./chunk-K4EOONYM.js";
|
|
19
|
+
import "./chunk-E7OIKX5Z.js";
|
|
20
20
|
import "./chunk-DGT54IH5.js";
|
|
21
21
|
|
|
22
22
|
// scripts/hooks/pretool-guard-cli.ts
|
|
@@ -8,19 +8,19 @@ import {
|
|
|
8
8
|
run_event_stream_emit,
|
|
9
9
|
run_headless,
|
|
10
10
|
session_language
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-EUMACUK2.js";
|
|
12
12
|
import {
|
|
13
13
|
error_text
|
|
14
14
|
} from "./chunk-CDY4NFQG.js";
|
|
15
15
|
import {
|
|
16
16
|
josh_environment_file
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-K4EOONYM.js";
|
|
18
18
|
import {
|
|
19
19
|
agent_session_environment,
|
|
20
20
|
json_value,
|
|
21
21
|
process_identity,
|
|
22
22
|
run_carry
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-E7OIKX5Z.js";
|
|
24
24
|
import {
|
|
25
25
|
stamp_file
|
|
26
26
|
} from "./chunk-DGT54IH5.js";
|
|
@@ -227,8 +227,9 @@ function ensure_ledger_directory(directory) {
|
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
function ledger_arguments(common_directory, profile) {
|
|
230
|
-
if (common_directory === void 0 || profile.role !== agent_role_profile.WORKER)
|
|
231
|
-
|
|
230
|
+
if (common_directory === void 0 || profile.role !== agent_role_profile.WORKER || path2.basename(common_directory) !== GIT_DIRECTORY) {
|
|
231
|
+
return [];
|
|
232
|
+
}
|
|
232
233
|
const directory = path2.join(path2.dirname(common_directory), LEDGER_DIRECTORY);
|
|
233
234
|
ensure_ledger_directory(directory);
|
|
234
235
|
return [ADD_DIRECTORY_FLAG, directory];
|
package/dist/hooks/stop-guard.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
repo_party,
|
|
14
14
|
run_cut,
|
|
15
15
|
run_hold
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-43ZHT22P.js";
|
|
17
17
|
import {
|
|
18
18
|
agent_headless,
|
|
19
19
|
agent_role_profile,
|
|
@@ -23,22 +23,22 @@ import {
|
|
|
23
23
|
run_event_stream_emit,
|
|
24
24
|
run_headless,
|
|
25
25
|
session_language
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-EUMACUK2.js";
|
|
27
27
|
import {
|
|
28
28
|
timed_fetch
|
|
29
29
|
} from "./chunk-723HKZO5.js";
|
|
30
30
|
import "./chunk-CDY4NFQG.js";
|
|
31
31
|
import {
|
|
32
32
|
hook_decision
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-J47HU5H5.js";
|
|
34
34
|
import {
|
|
35
35
|
time_density_hook,
|
|
36
36
|
time_hook_transcript,
|
|
37
37
|
time_reported_failure
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-AS74OU3D.js";
|
|
39
39
|
import {
|
|
40
40
|
lane_child_marker
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-K4EOONYM.js";
|
|
42
42
|
import {
|
|
43
43
|
backlog_budget,
|
|
44
44
|
issue_number_shape,
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
process_owner_schema,
|
|
48
48
|
run_carry,
|
|
49
49
|
run_invocation
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-E7OIKX5Z.js";
|
|
51
51
|
import {
|
|
52
52
|
stamp_file
|
|
53
53
|
} from "./chunk-DGT54IH5.js";
|
|
@@ -243,13 +243,16 @@ var NONE2 = 0;
|
|
|
243
243
|
async function live_lane_count() {
|
|
244
244
|
return lane_registry.live_count(await lane_registry.list_lanes());
|
|
245
245
|
}
|
|
246
|
+
async function free_lanes_beside(lanes) {
|
|
247
|
+
const limit = await lane_capacity.lane_limit();
|
|
248
|
+
if (limit.kind !== "limit") return void 0;
|
|
249
|
+
return lane_capacity.free_lanes(limit.limit, lane_registry.live_count(lanes));
|
|
250
|
+
}
|
|
246
251
|
async function free_under(limit) {
|
|
247
252
|
return lane_capacity.free_lanes(limit, await live_lane_count());
|
|
248
253
|
}
|
|
249
254
|
async function free_lane_count() {
|
|
250
|
-
|
|
251
|
-
if (limit.kind !== "limit") return NO_FREE;
|
|
252
|
-
return await free_under(limit.limit);
|
|
255
|
+
return await free_lanes_beside(await lane_registry.list_lanes()) ?? NO_FREE;
|
|
253
256
|
}
|
|
254
257
|
async function drive_free_lane_count() {
|
|
255
258
|
const limit = await lane_capacity.lane_limit();
|
|
@@ -306,6 +309,7 @@ var backlog_ready = {
|
|
|
306
309
|
read_backlog_next,
|
|
307
310
|
print_offer_hint,
|
|
308
311
|
free_lane_count,
|
|
312
|
+
free_lanes_beside,
|
|
309
313
|
live_lane_count,
|
|
310
314
|
drive_free_lane_count,
|
|
311
315
|
drains_pool,
|
|
@@ -317,6 +321,52 @@ var backlog_ready = {
|
|
|
317
321
|
|
|
318
322
|
// scripts/notify/telegram-notify.ts
|
|
319
323
|
import { z } from "zod";
|
|
324
|
+
|
|
325
|
+
// scripts/notify/confirmation-options.ts
|
|
326
|
+
var JAPANESE_LANG_PREFIX = "ja";
|
|
327
|
+
var JAPANESE_HEADINGS = {
|
|
328
|
+
recommended: "\u63A8\u5968:",
|
|
329
|
+
alternatives: "\u4ED6\u306E\u9078\u629E\u80A2:",
|
|
330
|
+
none: "\u306A\u3057"
|
|
331
|
+
};
|
|
332
|
+
var ENGLISH_HEADINGS = {
|
|
333
|
+
recommended: "Recommended:",
|
|
334
|
+
alternatives: "Alternatives:",
|
|
335
|
+
none: "none"
|
|
336
|
+
};
|
|
337
|
+
function headings() {
|
|
338
|
+
const { lang } = session_language.resolve_session_lang();
|
|
339
|
+
return lang.toLowerCase().startsWith(JAPANESE_LANG_PREFIX) ? JAPANESE_HEADINGS : ENGLISH_HEADINGS;
|
|
340
|
+
}
|
|
341
|
+
function alternatives_block(options, labels) {
|
|
342
|
+
if (options.alternatives.length === 0) return `${labels.alternatives} ${labels.none}`;
|
|
343
|
+
const lines = options.alternatives.map((alternative) => `- ${alternative}`);
|
|
344
|
+
return [labels.alternatives, ...lines].join("\n");
|
|
345
|
+
}
|
|
346
|
+
function block(options) {
|
|
347
|
+
const labels = headings();
|
|
348
|
+
return `${labels.recommended} ${options.recommended}
|
|
349
|
+
${alternatives_block(options, labels)}`;
|
|
350
|
+
}
|
|
351
|
+
var confirmation_options = { block };
|
|
352
|
+
|
|
353
|
+
// scripts/notify/notify-opt-in.ts
|
|
354
|
+
var OPT_IN_KEY = "JOSH_NOTIFY_OPT_IN";
|
|
355
|
+
var OPTIONAL_TASK_TYPES = /* @__PURE__ */ new Set(["planning", "completion"]);
|
|
356
|
+
var LIST_SEPARATOR = ",";
|
|
357
|
+
function opted_in_types() {
|
|
358
|
+
return (process.env[OPT_IN_KEY] ?? "").split(LIST_SEPARATOR).map((entry) => entry.trim().toLowerCase()).filter((entry) => entry.length > 0);
|
|
359
|
+
}
|
|
360
|
+
function is_skipped(task_type) {
|
|
361
|
+
if (!OPTIONAL_TASK_TYPES.has(task_type)) return false;
|
|
362
|
+
return !opted_in_types().includes(task_type);
|
|
363
|
+
}
|
|
364
|
+
function skip_line(task_type) {
|
|
365
|
+
return `\u{1F515} ${task_type} notifications are not opted in (${OPT_IN_KEY}).`;
|
|
366
|
+
}
|
|
367
|
+
var notify_opt_in = { is_skipped, skip_line };
|
|
368
|
+
|
|
369
|
+
// scripts/notify/telegram-notify.ts
|
|
320
370
|
var TELEGRAM_API_BASE = "https://api.telegram.org";
|
|
321
371
|
var TELEGRAM_TEXT_LIMIT = 4096;
|
|
322
372
|
var BODY_TRUNCATION_MARK = "\n...";
|
|
@@ -377,6 +427,12 @@ function load_config() {
|
|
|
377
427
|
function is_notify_disabled() {
|
|
378
428
|
return parse_environment_string(process.env[NOTIFY_SWITCH_KEY]).toLowerCase() === NOTIFY_OFF_VALUE;
|
|
379
429
|
}
|
|
430
|
+
function skip_line2(task_type) {
|
|
431
|
+
if (is_notify_disabled()) {
|
|
432
|
+
return `\u{1F515} Telegram notifications are disabled (${NOTIFY_SWITCH_KEY}=${NOTIFY_OFF_VALUE}).`;
|
|
433
|
+
}
|
|
434
|
+
return notify_opt_in.is_skipped(task_type) ? notify_opt_in.skip_line(task_type) : void 0;
|
|
435
|
+
}
|
|
380
436
|
function build_header(task_type, repo_name) {
|
|
381
437
|
const { icon, label } = TASK_DEFINITIONS[task_type];
|
|
382
438
|
if (repo_name === void 0 || repo_name.length === 0) return `${icon} ${label}`;
|
|
@@ -402,6 +458,7 @@ function build_url_parts(input) {
|
|
|
402
458
|
function build_blocks(input) {
|
|
403
459
|
const blocks = [build_title_block(input)];
|
|
404
460
|
push_if_present(blocks, input.body);
|
|
461
|
+
push_if_present(blocks, input.choices);
|
|
405
462
|
blocks.push(...build_url_parts(input));
|
|
406
463
|
return blocks;
|
|
407
464
|
}
|
|
@@ -435,10 +492,9 @@ function build_send_failure(error, config) {
|
|
|
435
492
|
return new Error(`${SEND_FAILED_PREFIX}: ${reason}`, { cause: new Error(reason) });
|
|
436
493
|
}
|
|
437
494
|
async function send(input) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
);
|
|
495
|
+
const skipped = skip_line2(input.task_type);
|
|
496
|
+
if (skipped !== void 0) {
|
|
497
|
+
console.info(skipped);
|
|
442
498
|
return;
|
|
443
499
|
}
|
|
444
500
|
const config = load_config();
|
|
@@ -487,6 +543,7 @@ async function confirm(input) {
|
|
|
487
543
|
repo_name: gh_spawn.get_repo_name_with_owner_within(REPO_LOOKUP_TIMEOUT_MS),
|
|
488
544
|
issue_title: input.issue_title,
|
|
489
545
|
body: input.body,
|
|
546
|
+
choices: confirmation_options.block(input),
|
|
490
547
|
issue_url: void 0,
|
|
491
548
|
pr_url: void 0
|
|
492
549
|
},
|
|
@@ -762,23 +819,23 @@ var stop_payload_schema = z3.object({
|
|
|
762
819
|
last_assistant_message: z3.string().nullish()
|
|
763
820
|
});
|
|
764
821
|
var NO_OUTCOME = { reason: void 0 };
|
|
765
|
-
var STOP_NOTIFY_REASON = '\u26D4 mid-workflow stop notification: this working tree is still held by a run and no `confirmation` Telegram was sent this turn
|
|
766
|
-
var HOLD_RELEASE_REASON = "\u26D4 working-tree hold not released: this working tree is clean but its `run:hold` record is still in place
|
|
822
|
+
var STOP_NOTIFY_REASON = '\u26D4 mid-workflow stop notification: this working tree is still held by a run and no `confirmation` Telegram was sent this turn. Send `pnpm josh notify --task-type confirmation --issue-url "<url>" --body=$\'<reason>\' --recommended "<choice>" --alternative "<choice>"` (`CLAUDE.md` \u2192 "Mid-workflow stop notification"), then confirm in one line that it was sent \u2014 do not repeat your previous reply.';
|
|
823
|
+
var HOLD_RELEASE_REASON = "\u26D4 working-tree hold not released: this working tree is clean but its `run:hold` record is still in place. Release it with `pnpm josh run:release <N>` (bare for a `new` entry; `working-tree-hold.md`), then confirm in one line that it was released \u2014 do not repeat your previous reply.";
|
|
767
824
|
var ISSUE_CITATION_REASON = "Session-facing output cites an Issue as a number-link so the reader can click through and see which repository it is (`CLAUDE.md`, `prompts/collaboration-workflow/issue-citation.md`).";
|
|
768
825
|
function build_citation_reason(references) {
|
|
769
826
|
const numbers = references.join(", ");
|
|
770
827
|
const command = `pnpm josh issue:cite ${issue_citation.cite_arguments(references).join(" ")}`;
|
|
771
828
|
return `\u26D4 issue citation: your reply names an Issue as a bare \`#N\` (${numbers}). Run \`${command}\` to print the paste-ready citation lines, then print the corrected citation lines alone \u2014 do not repeat your previous reply. ${ISSUE_CITATION_REASON}`;
|
|
772
829
|
}
|
|
773
|
-
var FILING_OFFER_REASON = '\u26D4 filing offer: your reply offers to file an Issue instead of filing it, and this run is unattended \u2014 nobody is there to answer.
|
|
830
|
+
var FILING_OFFER_REASON = '\u26D4 filing offer: your reply offers to file an Issue instead of filing it, and this run is unattended \u2014 nobody is there to answer. Run `pnpm josh issue:file "<title>" --body-file <path> --depth <0|1|2>` (Tier A, `observation-filing.md`), then end with the one-line citation of what was filed; do not repeat your previous reply. If it is not worth filing after all, say so in one line instead.';
|
|
774
831
|
var HEADLESS_WAIT_MARKER = "\u26D4 headless parent:";
|
|
775
832
|
var HEADLESS_REFUSAL_CAP = 3;
|
|
776
833
|
var HEADLESS_WAIT_CALLS = ['"command":"pnpm josh lane:await'];
|
|
777
|
-
var HEADLESS_WAIT_BODY = ' this is a `claude -p` `backlogrun` parent
|
|
834
|
+
var HEADLESS_WAIT_BODY = ' this is a `claude -p` `backlogrun` parent with lanes in flight, and ending this turn kills the process and its background waits. Hand the loop back with `pnpm josh run:carry --cut --owner "$PPID"` (or `--end` when the run is over), then end the turn (`backlogrun-progress.md`).';
|
|
778
835
|
var HEADLESS_WAIT_REASON = `${HEADLESS_WAIT_MARKER}${HEADLESS_WAIT_BODY}`;
|
|
779
836
|
var INDEX_COMMAND_PATTERN = /git (?:add|stage|rm --cached|restore --staged|restore -S)\b/u;
|
|
780
837
|
var PERMISSION_PATTERN = /許可|承認|permission|approve|approval|authorization/iu;
|
|
781
|
-
var LANE_INDEX_REASON =
|
|
838
|
+
var LANE_INDEX_REASON = "\u26D4 lane index permission: this is a dispatched lane child (`JOSH_LANE_CHILD`) and your reply asks a person for permission to change the git index. That is Tier A here (`chain-rule.md`): remove any conflict markers, run `pnpm josh git -y` (it stages and commits, a conflicted merge included) and continue the run \u2014 do not repeat your previous reply.";
|
|
782
839
|
function asks_index_permission(message2) {
|
|
783
840
|
return INDEX_COMMAND_PATTERN.test(message2) && PERMISSION_PATTERN.test(message2);
|
|
784
841
|
}
|
package/dist/josh.js
CHANGED
|
@@ -743,8 +743,9 @@ function is_worker_flag(argument) {
|
|
|
743
743
|
return WORKER_FLAGS.some((flag) => argument === flag || argument.startsWith(`${flag}=`));
|
|
744
744
|
}
|
|
745
745
|
function worker_arguments(vitest_arguments, share) {
|
|
746
|
-
if (share === void 0)
|
|
747
|
-
|
|
746
|
+
if (share === void 0 || vitest_arguments.some((argument) => is_worker_flag(argument))) {
|
|
747
|
+
return [];
|
|
748
|
+
}
|
|
748
749
|
return [`${WORKER_FLAG}=${String(share)}`];
|
|
749
750
|
}
|
|
750
751
|
function mark_run_started(target) {
|
|
@@ -2747,7 +2748,7 @@ var WORKFLOW_COMMANDS = {
|
|
|
2747
2748
|
description: "Send Telegram notification",
|
|
2748
2749
|
category: "Workflow",
|
|
2749
2750
|
reference: [
|
|
2750
|
-
"[--task-type <type>] [--body <text> | --body-file <path>] [--issue-url <url>] [--pr-url <url>] [--issue-title <text>] [--repo-name <name>]",
|
|
2751
|
+
"[--task-type <type>] [--body <text> | --body-file <path>] [--issue-url <url>] [--pr-url <url>] [--issue-title <text>] [--repo-name <name>] [--recommended <text>] [--alternative <text>]...",
|
|
2751
2752
|
"automation",
|
|
2752
2753
|
["notifications"]
|
|
2753
2754
|
],
|
|
@@ -3024,8 +3025,7 @@ function parse_scp_like(url) {
|
|
|
3024
3025
|
const user_end = url.indexOf(USER_SEPARATOR);
|
|
3025
3026
|
const authority = user_end === NOT_FOUND ? url : url.slice(user_end + 1);
|
|
3026
3027
|
const host_end = authority.indexOf(HOST_SEPARATOR);
|
|
3027
|
-
if (host_end === NOT_FOUND) return void 0;
|
|
3028
|
-
if (!is_github_ssh_host(authority.slice(0, host_end))) return void 0;
|
|
3028
|
+
if (host_end === NOT_FOUND || !is_github_ssh_host(authority.slice(0, host_end))) return void 0;
|
|
3029
3029
|
return to_identity(authority.slice(host_end + 1));
|
|
3030
3030
|
}
|
|
3031
3031
|
function parse_url_like(url) {
|
|
@@ -3053,8 +3053,7 @@ function origin_section_lines(lines) {
|
|
|
3053
3053
|
}
|
|
3054
3054
|
function url_value(line) {
|
|
3055
3055
|
const separator = line.indexOf("=");
|
|
3056
|
-
if (separator === NOT_FOUND) return void 0;
|
|
3057
|
-
if (line.slice(0, separator).trim() !== URL_KEY) return void 0;
|
|
3056
|
+
if (separator === NOT_FOUND || line.slice(0, separator).trim() !== URL_KEY) return void 0;
|
|
3058
3057
|
return line.slice(separator + 1).trim();
|
|
3059
3058
|
}
|
|
3060
3059
|
function parse_origin_from_config(content) {
|
|
@@ -18,8 +18,7 @@ function is_marked(text) {
|
|
|
18
18
|
return text.startsWith(MARKER_PREFIX);
|
|
19
19
|
}
|
|
20
20
|
function apply_marker_for_destination(destination, text, package_name) {
|
|
21
|
-
if (!is_workflow_destination(destination)) return text;
|
|
22
|
-
if (is_marked(text)) return text;
|
|
21
|
+
if (!is_workflow_destination(destination) || is_marked(text)) return text;
|
|
23
22
|
return `${marker_block(package_name)}${text}`;
|
|
24
23
|
}
|
|
25
24
|
var managed_marker_logic = {
|
package/dist/version/index.js
CHANGED
|
@@ -141,8 +141,7 @@ function read_matching_version(manifest_path, package_name) {
|
|
|
141
141
|
const parsed = package_named_version_schema.safeParse(
|
|
142
142
|
json_value.parse_or_undefined(readFileSync(manifest_path, "utf8"))
|
|
143
143
|
);
|
|
144
|
-
if (!parsed.success) return void 0;
|
|
145
|
-
if (parsed.data.name !== package_name) return void 0;
|
|
144
|
+
if (!parsed.success || parsed.data.name !== package_name) return void 0;
|
|
146
145
|
return parsed.data.version;
|
|
147
146
|
}
|
|
148
147
|
function walk_up_for_version(start_directory, package_name) {
|
|
@@ -152,9 +151,9 @@ function walk_up_for_version(start_directory, package_name) {
|
|
|
152
151
|
}
|
|
153
152
|
return void 0;
|
|
154
153
|
}
|
|
155
|
-
function resolve_from_base(base_url, package_name, resolve_marker) {
|
|
154
|
+
function resolve_from_base(base_url, package_name, resolve_marker = package_name) {
|
|
156
155
|
try {
|
|
157
|
-
return createRequire(base_url).resolve(resolve_marker
|
|
156
|
+
return createRequire(base_url).resolve(resolve_marker);
|
|
158
157
|
} catch {
|
|
159
158
|
return void 0;
|
|
160
159
|
}
|
|
@@ -281,8 +280,9 @@ function is_latest_withheld(times, latest, minimum_age_minutes, now_ms) {
|
|
|
281
280
|
return published_ms > now_ms - minimum_age_minutes * MS_PER_MINUTE2;
|
|
282
281
|
}
|
|
283
282
|
function resolve_installable(times, latest, minimum_age_minutes, now_ms) {
|
|
284
|
-
if (times === void 0
|
|
285
|
-
|
|
283
|
+
if (times === void 0 || !is_latest_withheld(times, latest, minimum_age_minutes, now_ms)) {
|
|
284
|
+
return void 0;
|
|
285
|
+
}
|
|
286
286
|
const installable = release_age.select_aged_version(times, void 0, minimum_age_minutes, now_ms);
|
|
287
287
|
return installable === latest ? void 0 : installable;
|
|
288
288
|
}
|
|
@@ -307,8 +307,9 @@ function format_release_hold_note(version, latest, installable, minimum_age_minu
|
|
|
307
307
|
return `${head}; an unpinned resolve lands on ${installable}`;
|
|
308
308
|
}
|
|
309
309
|
function build_release_hold_notes(version, latest, installable, minimum_age_minutes) {
|
|
310
|
-
if (version === void 0 || installable === void 0)
|
|
311
|
-
|
|
310
|
+
if (version === void 0 || installable === void 0 || !is_release_age_hold(version, latest, installable)) {
|
|
311
|
+
return [];
|
|
312
|
+
}
|
|
312
313
|
return [format_release_hold_note(version, latest, installable, minimum_age_minutes)];
|
|
313
314
|
}
|
|
314
315
|
var release_hold = {
|
|
@@ -1399,8 +1400,9 @@ function build_extras(config) {
|
|
|
1399
1400
|
}
|
|
1400
1401
|
function build_upstream_effective(upstream, context) {
|
|
1401
1402
|
const { resolve_effective_version, resolve_global_upgrade_command } = upstream;
|
|
1402
|
-
if (resolve_effective_version === void 0
|
|
1403
|
-
|
|
1403
|
+
if (resolve_effective_version === void 0 || resolve_global_upgrade_command === void 0) {
|
|
1404
|
+
return void 0;
|
|
1405
|
+
}
|
|
1404
1406
|
return {
|
|
1405
1407
|
version: resolve_effective_version(context),
|
|
1406
1408
|
upgrade_command: resolve_global_upgrade_command(context)
|
|
@@ -1485,8 +1487,9 @@ function build_idle_message(reports) {
|
|
|
1485
1487
|
}
|
|
1486
1488
|
function describe_effective_outcome(upstream, report, snapshot) {
|
|
1487
1489
|
const { resolve_effective_version } = upstream;
|
|
1488
|
-
if (resolve_effective_version === void 0 || report === void 0)
|
|
1489
|
-
|
|
1490
|
+
if (resolve_effective_version === void 0 || report === void 0 || version_check_logic.build_effective_upgrade_commands(report).length === 0) {
|
|
1491
|
+
return [];
|
|
1492
|
+
}
|
|
1490
1493
|
const after = resolve_effective_version({
|
|
1491
1494
|
latest: snapshot.latest,
|
|
1492
1495
|
upstream_latest: report.latest
|
package/eslint/base.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
SPEC_FILENAME_PATTERNS,
|
|
30
30
|
} from './rules/test-filename.js'
|
|
31
31
|
import { typescript_rules } from './rules/typescript.js'
|
|
32
|
-
import { unicorn_rules } from './rules/unicorn.js'
|
|
32
|
+
import { unicorn_rules, unicorn_test_rules } from './rules/unicorn.js'
|
|
33
33
|
|
|
34
34
|
const FILE_PATTERNS = {
|
|
35
35
|
d_ts: ['**/*.d.ts'],
|
|
@@ -234,6 +234,7 @@ export function create_base_config({ gitignore_path, tsconfig_root_dir }) {
|
|
|
234
234
|
// `expect(x).toBe(0.05)` compares deterministic config constants, not computed
|
|
235
235
|
// floats; working around the rule only weakens the assertion.
|
|
236
236
|
'sonarjs/no-floating-point-equality': 'off',
|
|
237
|
+
...unicorn_test_rules,
|
|
237
238
|
},
|
|
238
239
|
},
|
|
239
240
|
{
|
package/eslint/rules/unicorn.js
CHANGED
|
@@ -205,3 +205,19 @@ export const unicorn_rules = {
|
|
|
205
205
|
// たびにエディタと衝突し、可読性の利得なく差分ノイズだけを生むため無効化する(joshuafolkken/kit#3273)。
|
|
206
206
|
'unicorn/no-asterisk-prefix-in-documentation-comments': 'off',
|
|
207
207
|
}
|
|
208
|
+
|
|
209
|
+
// unicorn 78 のベースライン方針(joshuafolkken/kit#3882): 78 は新ルール 2 つ
|
|
210
|
+
// (no-unnecessary-default-arguments / no-repeated-call-wrappers)に加え、型解決とコメントを含む
|
|
211
|
+
// コードの検査を広げたため、既存ルールが新たに報告する。prefer-combined-guards /
|
|
212
|
+
// prefer-minimal-ternary / no-negated-condition / prefer-default-parameters は正当な
|
|
213
|
+
// クリーンアップなので採用し、コードを直す。consistent-boolean-name だけは下記のとおり
|
|
214
|
+
// テストファイルで外す。
|
|
215
|
+
export const unicorn_test_rules = {
|
|
216
|
+
// 78 は vi.fn() / vi.spyOn() / vi.mocked() の戻り型を解決できるようになり、真偽値を返す関数の
|
|
217
|
+
// モックやスパイ(`const write = vi.spyOn(process.stdout, 'write')`)を真偽値の束縛として報告する。
|
|
218
|
+
// 関数値の const を checkVariables で検査するのはプラグインの文書どおりの仕様(77 でも
|
|
219
|
+
// `const f = () => true` は報告される)で、誤検知ではない。ただしテストの束縛はほぼすべて
|
|
220
|
+
// 差し替える関数を名前で示すテストダブルで、`is_write` のような名前は述語の結果のように読めて
|
|
221
|
+
// 誤解を招く。kit が関数名を検査しない(checkFunctions: 'never')のと同じ理由でテストでは外す。
|
|
222
|
+
'unicorn/consistent-boolean-name': 'off',
|
|
223
|
+
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.1471.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": [
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
"eslint-plugin-import-x": "^4.17.1",
|
|
179
179
|
"eslint-plugin-promise": "^7.3.0",
|
|
180
180
|
"eslint-plugin-sonarjs": "^4.2.1",
|
|
181
|
-
"eslint-plugin-unicorn": "^
|
|
181
|
+
"eslint-plugin-unicorn": "^78.0.0",
|
|
182
182
|
"globals": "^17.12.0",
|
|
183
183
|
"prettier": "^3.9.9",
|
|
184
184
|
"prettier-plugin-svelte": "^4.1.1",
|
|
@@ -260,7 +260,7 @@
|
|
|
260
260
|
"eslint-plugin-import-x": "^4.17.1",
|
|
261
261
|
"eslint-plugin-promise": "^7.3.0",
|
|
262
262
|
"eslint-plugin-sonarjs": "^4.2.2",
|
|
263
|
-
"eslint-plugin-unicorn": "^
|
|
263
|
+
"eslint-plugin-unicorn": "^78.0.0",
|
|
264
264
|
"eslint_d": "^15.0.3",
|
|
265
265
|
"globals": "^17.13.0",
|
|
266
266
|
"lefthook": "^2.2.1",
|
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
# コーディング指針 — lint では表せない書き方
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
lint・型検査の実行手順は `CLAUDE.md` → "Code Change Rules" の検証ゲート(`pnpm josh gate`、実装中は `pnpm josh lint:related` / `pnpm josh test:related`)が単一ソースである。
|
|
3
|
+
関数の構文・品質上限・型安全・早期 return・マジックナンバーは `CLAUDE.md` → "Critical Conventions (non-standard — always apply)"、lint・型検査の実行は `CLAUDE.md` → "Code Change Rules"(`pnpm josh gate`、実装中は `pnpm josh lint:related` / `pnpm josh test:related`)に従う。ここにない命名の細目(クラスのプロパティ・メソッドの `snake_case` など)は `eslint/rules/naming-convention.js` が持つ。**`function` 構文(アロー関数を使わない)と早期 return の 1 行形式は lint が検査しない**ので、書き手とレビューが確かめる。
|
|
6
4
|
|
|
7
5
|
## Conventions
|
|
8
6
|
|
|
9
|
-
`
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
- **Files**: Svelte `PascalCase.svelte(.ts)` · TypeScript `kebab-case.ts` · tests `*.test.ts` / `*.svelte.test.ts`, colocated, never `*.spec.ts` (`prompts/testing-guide.md`) · in `scripts/`, no `../` imports — use `#scripts/*`
|
|
14
|
-
- **Content rules**: user-visible strings use i18n message keys in every locale · comments / test titles English only (`eslint/rules/` may explain rationale in Japanese) · no duplication; `/* @refactor-ignore */` at file top excludes a file from refactoring
|
|
7
|
+
- Naming: `snake_case` variables / functions / params · `PascalCase` types / classes / interfaces / enums · `UPPER_CASE` enum members · booleans prefixed `is_` / `has_` / `should_` / `can_` / `will_` / `did_` · constants `UPPER_CASE` or `snake_case`
|
|
8
|
+
- Functions & exports: multiple functions → a namespace object `export { my_module }` (constants exempt) · no `export default`
|
|
9
|
+
- Files: Svelte `PascalCase.svelte(.ts)` · TypeScript `kebab-case.ts` · tests `*.test.ts` / `*.svelte.test.ts`, colocated, never `*.spec.ts` (`prompts/testing-guide.md`) · in `scripts/`, no `../` imports — use `#scripts/*`
|
|
10
|
+
- Content rules: user-visible strings use i18n message keys in every locale · comments / test titles English only (`eslint/rules/` may explain rationale in Japanese) · no duplication; `/* @refactor-ignore */` at file top excludes a file from refactoring
|
|
15
11
|
|
|
16
12
|
## 📝 基本方針
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
- **コメントは「なぜ」だけ、経緯は書かない**: 残すのは一行の理由(そのルールの意図)だけ。「以前は…」という経緯、Issue 番号への参照、計測値は git 履歴と Issue が保持している
|
|
22
|
-
- **文字列も定数化する**: 数値リテラルの抽出は lint が強制するが、繰り返し使用する文字列や識別子も定数化し、意味の分かる名前を付ける
|
|
14
|
+
- **意図が不明瞭な処理は関数に抽出する**: 1 行でも抽出し、関数名で意図を表す(`if (is_eligible_for_service(user))`)
|
|
15
|
+
- **コメントは「なぜ」だけ**: 一行の理由だけを残す。「以前は…」の経緯・Issue 番号・計測値は書かない(git 履歴と Issue が持つ)
|
|
16
|
+
- **文字列も定数化する**: 繰り返す文字列や識別子にも意味の分かる名前の定数を付ける
|
|
23
17
|
- **既存のコード体系に寄り添う**: そのうえで、より良く書けるなら目指す
|
|
24
|
-
- **仕組みを足す前に原因を問う**:
|
|
18
|
+
- **仕組みを足す前に原因を問う**: `prompts/collaboration-workflow/principles.md` → "elegant-design"。重複の撲滅は "no-clones"
|
|
25
19
|
|
|
26
20
|
## 📁 新規作成時の手順
|
|
27
21
|
|
|
@@ -34,16 +28,12 @@ find src -name "*.ts" -o -name "*.svelte" | grep -i [関連キーワード]
|
|
|
34
28
|
|
|
35
29
|
### 2. ファイル分割の指針
|
|
36
30
|
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
- **メインファイルの肥大化を避ける**: メインファイルの肥大化を避けることを優先する。再利用可能な機能や独立した責任を持つ機能は、積極的に別ファイルに分割する。メインファイルは主要な処理フローに集中し、詳細な実装は別ファイルに分離する
|
|
41
|
-
- **過度な分割は避ける**: 小さすぎるファイルの分割は避け、関連する機能は同じファイルにまとめる
|
|
31
|
+
- `CLAUDE.md` → "Quality limits" の上限に近づいたら分割を検討する。編集前に `pnpm josh lines <path>` で余裕を確認する
|
|
32
|
+
- 責任ごと、また他ファイルからも使われうるロジックごとに別ファイルに分け、メインファイルは主要な処理フローに集中させる
|
|
33
|
+
- 小さすぎる分割は避け、関連する機能は同じファイルにまとめる
|
|
42
34
|
|
|
43
35
|
### 3. 名前空間オブジェクトの名付け方
|
|
44
36
|
|
|
45
|
-
複数の関数を名前空間オブジェクトにまとめてエクスポートする規則そのものは上記「Conventions」にある(定数は個別エクスポートでよい)。ここでは名付け方だけを述べる。
|
|
46
|
-
|
|
47
37
|
- ファイル名と名前空間名で意図を明確にする(例: `git-command.ts` → `git_command`)
|
|
48
38
|
- メソッド名は短く、名前空間で補完する(例: `exec_git_branch()` → `git_command.branch()`)
|
|
49
39
|
|