@karmaniverous/jeeves 0.3.0 → 0.3.1
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/content/agents-section.md +9 -3
- package/content/soul-section.md +1 -0
- package/dist/cli/jeeves/index.js +62 -8
- package/dist/index.d.ts +3 -0
- package/dist/index.js +62 -7
- package/package.json +1 -1
|
@@ -177,11 +177,17 @@ No stranded local branches. Push immediately after commit. A commit that isn't p
|
|
|
177
177
|
|
|
178
178
|
### Check PR State Before Pushing
|
|
179
179
|
|
|
180
|
-
**Before EVERY `git push`**,
|
|
180
|
+
**Before EVERY `git push`**, run `gh pr list --head <branch> --repo <repo> --json number,state` to check whether a PR exists on that branch and whether it's merged.
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
- **No PR exists:** Safe to push.
|
|
183
|
+
- **PR is `OPEN`:** Safe to push.
|
|
184
|
+
- **PR is `MERGED` or `CLOSED`:** **STOP** and report to the user. Do not push to a merged PR branch.
|
|
183
185
|
|
|
184
|
-
This is not optional. It applies to every push, every branch, every time.
|
|
186
|
+
This is not optional. It applies to every push, every branch, every time. No judgment call about whether the branch "is a PR branch" — the check is mechanical.
|
|
187
|
+
|
|
188
|
+
### New PR Over Merged Branch
|
|
189
|
+
|
|
190
|
+
When a PR has been merged and additional work is needed on the same branch, create a new PR on the **same branch** targeting the same base. Do not create new branches, cherry-pick, or start over. The commits are already there — `gh pr create --head <existing-branch>` is the entire operation.
|
|
185
191
|
|
|
186
192
|
## Managed Content Self-Maintenance
|
|
187
193
|
|
package/content/soul-section.md
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
I am a **senior software engineer** first. The persona is style; the engineering discipline is substance.
|
|
22
22
|
|
|
23
23
|
What this means in practice:
|
|
24
|
+
- **Do not execute untested code.** Every mutation script defaults to dry-run mode. The dry-run output is the test — it shows what would happen. Live execution requires an explicit flag. If dry-run is hard to implement, that's a design flaw.
|
|
24
25
|
- **No cowboy coding.** I don't iterate in production. I don't ship untested changes. I don't treat live systems as scratch pads.
|
|
25
26
|
- **I follow proper workflows.** Branch, test, review, merge. CI/CD exists for a reason. If there's a pipeline, I use it.
|
|
26
27
|
- **I resist n00b temptations.** "Let me just quickly…" in prod is how outages happen. I know better.
|
package/dist/cli/jeeves/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
#!/usr/bin/env node
|
|
3
2
|
import require$$0 from 'commander';
|
|
4
3
|
import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync, cpSync, rmSync } from 'node:fs';
|
|
5
4
|
import { join, dirname } from 'node:path';
|
|
@@ -104,6 +103,12 @@ const AGENTS_MARKERS = {
|
|
|
104
103
|
/** H1 title prepended in the managed block. */
|
|
105
104
|
title: 'Jeeves Platform Agents',
|
|
106
105
|
};
|
|
106
|
+
/** All known marker sets — single source of truth for cross-contamination detection. */
|
|
107
|
+
const ALL_MARKERS = [
|
|
108
|
+
TOOLS_MARKERS,
|
|
109
|
+
SOUL_MARKERS,
|
|
110
|
+
AGENTS_MARKERS,
|
|
111
|
+
];
|
|
107
112
|
/**
|
|
108
113
|
* Regex pattern to extract version stamp from a BEGIN marker comment.
|
|
109
114
|
*
|
|
@@ -200,14 +205,14 @@ const SECTION_ORDER = [
|
|
|
200
205
|
* Core library version, inlined at build time.
|
|
201
206
|
*
|
|
202
207
|
* @remarks
|
|
203
|
-
* The `0.
|
|
208
|
+
* The `0.3.0` placeholder is replaced by
|
|
204
209
|
* `@rollup/plugin-replace` during the build with the actual version
|
|
205
210
|
* from `package.json`. This ensures the correct version survives
|
|
206
211
|
* when consumers bundle core into their own dist (where runtime
|
|
207
212
|
* `import.meta.url`-based resolution would find the wrong package.json).
|
|
208
213
|
*/
|
|
209
214
|
/** The core library version from package.json (inlined at build time). */
|
|
210
|
-
const CORE_VERSION = '0.
|
|
215
|
+
const CORE_VERSION = '0.3.0';
|
|
211
216
|
|
|
212
217
|
/**
|
|
213
218
|
* Core configuration schema and resolution.
|
|
@@ -541,11 +546,17 @@ No stranded local branches. Push immediately after commit. A commit that isn't p
|
|
|
541
546
|
|
|
542
547
|
### Check PR State Before Pushing
|
|
543
548
|
|
|
544
|
-
**Before EVERY \`git push\`**,
|
|
549
|
+
**Before EVERY \`git push\`**, run \`gh pr list --head <branch> --repo <repo> --json number,state\` to check whether a PR exists on that branch and whether it's merged.
|
|
550
|
+
|
|
551
|
+
- **No PR exists:** Safe to push.
|
|
552
|
+
- **PR is \`OPEN\`:** Safe to push.
|
|
553
|
+
- **PR is \`MERGED\` or \`CLOSED\`:** **STOP** and report to the user. Do not push to a merged PR branch.
|
|
545
554
|
|
|
546
|
-
|
|
555
|
+
This is not optional. It applies to every push, every branch, every time. No judgment call about whether the branch "is a PR branch" — the check is mechanical.
|
|
547
556
|
|
|
548
|
-
|
|
557
|
+
### New PR Over Merged Branch
|
|
558
|
+
|
|
559
|
+
When a PR has been merged and additional work is needed on the same branch, create a new PR on the **same branch** targeting the same base. Do not create new branches, cherry-pick, or start over. The commits are already there — \`gh pr create --head <existing-branch>\` is the entire operation.
|
|
549
560
|
|
|
550
561
|
## Managed Content Self-Maintenance
|
|
551
562
|
|
|
@@ -581,6 +592,7 @@ var soulSectionContent = `## Core Truths
|
|
|
581
592
|
I am a **senior software engineer** first. The persona is style; the engineering discipline is substance.
|
|
582
593
|
|
|
583
594
|
What this means in practice:
|
|
595
|
+
- **Do not execute untested code.** Every mutation script defaults to dry-run mode. The dry-run output is the test — it shows what would happen. Live execution requires an explicit flag. If dry-run is hard to implement, that's a design flaw.
|
|
584
596
|
- **No cowboy coding.** I don't iterate in production. I don't ship untested changes. I don't treat live systems as scratch pads.
|
|
585
597
|
- **I follow proper workflows.** Branch, test, review, merge. CI/CD exists for a reason. If there's a pipeline, I use it.
|
|
586
598
|
- **I resist n00b temptations.** "Let me just quickly…" in prod is how outages happen. I know better.
|
|
@@ -1024,6 +1036,48 @@ function parseManaged(fileContent, markers = TOOLS_MARKERS) {
|
|
|
1024
1036
|
};
|
|
1025
1037
|
}
|
|
1026
1038
|
|
|
1039
|
+
/**
|
|
1040
|
+
* Strip foreign managed blocks from content.
|
|
1041
|
+
*
|
|
1042
|
+
* @remarks
|
|
1043
|
+
* Prevents cross-contamination by removing managed blocks that belong
|
|
1044
|
+
* to other marker sets. For example, when writing TOOLS.md with TOOLS
|
|
1045
|
+
* markers, any SOUL or AGENTS managed blocks found in the user content
|
|
1046
|
+
* zone are stripped — they don't belong there.
|
|
1047
|
+
*
|
|
1048
|
+
* @packageDocumentation
|
|
1049
|
+
*/
|
|
1050
|
+
/**
|
|
1051
|
+
* Build a regex that matches an entire managed block (BEGIN marker through END marker).
|
|
1052
|
+
*
|
|
1053
|
+
* @param markers - The marker set to match.
|
|
1054
|
+
* @returns A regex that matches the full block including markers.
|
|
1055
|
+
*/
|
|
1056
|
+
function buildBlockPattern(markers) {
|
|
1057
|
+
const escapedBegin = markers.begin.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1058
|
+
const escapedEnd = markers.end.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1059
|
+
return new RegExp(`\\s*<!--\\s*${escapedBegin}(?:\\s*\\|[^>]*)?\\s*(?:—[^>]*)?\\s*-->[\\s\\S]*?<!--\\s*${escapedEnd}\\s*-->\\s*`, 'g');
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* Strip managed blocks belonging to foreign marker sets from content.
|
|
1063
|
+
*
|
|
1064
|
+
* @param content - The content to clean (typically user content zone).
|
|
1065
|
+
* @param currentMarkers - The marker set that owns this file (will NOT be stripped).
|
|
1066
|
+
* @returns Content with foreign managed blocks removed.
|
|
1067
|
+
*/
|
|
1068
|
+
function stripForeignMarkers(content, currentMarkers) {
|
|
1069
|
+
let result = content;
|
|
1070
|
+
for (const markers of ALL_MARKERS) {
|
|
1071
|
+
// Skip the current file's own markers
|
|
1072
|
+
if (markers.begin === currentMarkers.begin)
|
|
1073
|
+
continue;
|
|
1074
|
+
const pattern = buildBlockPattern(markers);
|
|
1075
|
+
result = result.replace(pattern, '\n');
|
|
1076
|
+
}
|
|
1077
|
+
// Clean up multiple blank lines left by removals
|
|
1078
|
+
return result.replace(/\n{3,}/g, '\n\n').trim();
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1027
1081
|
/**
|
|
1028
1082
|
* Version-stamp parsing and convergence logic.
|
|
1029
1083
|
*
|
|
@@ -1140,8 +1194,8 @@ async function updateManagedSection(filePath, content, options = {}) {
|
|
|
1140
1194
|
? `# ${markers.title}\n\n${sectionText}`
|
|
1141
1195
|
: sectionText;
|
|
1142
1196
|
}
|
|
1143
|
-
//
|
|
1144
|
-
const userContent = parsed.userContent;
|
|
1197
|
+
// Strip foreign managed blocks from user content (cross-contamination fix)
|
|
1198
|
+
const userContent = stripForeignMarkers(parsed.userContent, markers);
|
|
1145
1199
|
const cleanupNeeded = needsCleanup(newManagedBody, userContent);
|
|
1146
1200
|
// Build the full managed block
|
|
1147
1201
|
const beginLine = formatBeginMarker(markers.begin, coreVersion);
|
package/dist/index.d.ts
CHANGED
|
@@ -910,7 +910,9 @@ declare function patchConfig(config: Record<string, unknown>, pluginId: string,
|
|
|
910
910
|
interface ToolResult {
|
|
911
911
|
/** Content blocks — typically a single text block. */
|
|
912
912
|
content: Array<{
|
|
913
|
+
/** MIME type identifier (e.g. `"text"`). */
|
|
913
914
|
type: string;
|
|
915
|
+
/** Text content of the block. */
|
|
914
916
|
text: string;
|
|
915
917
|
}>;
|
|
916
918
|
/** Whether this result represents an error. */
|
|
@@ -955,6 +957,7 @@ interface PluginApi {
|
|
|
955
957
|
plugins?: {
|
|
956
958
|
/** Plugin entries keyed by plugin ID. */
|
|
957
959
|
entries?: Record<string, {
|
|
960
|
+
/** Plugin-specific configuration key-value pairs. */
|
|
958
961
|
config?: Record<string, unknown>;
|
|
959
962
|
}>;
|
|
960
963
|
};
|
package/dist/index.js
CHANGED
|
@@ -80,14 +80,14 @@ const COMPONENT_VERSIONS_FILE = 'component-versions.json';
|
|
|
80
80
|
* Core library version, inlined at build time.
|
|
81
81
|
*
|
|
82
82
|
* @remarks
|
|
83
|
-
* The `0.
|
|
83
|
+
* The `0.3.0` placeholder is replaced by
|
|
84
84
|
* `@rollup/plugin-replace` during the build with the actual version
|
|
85
85
|
* from `package.json`. This ensures the correct version survives
|
|
86
86
|
* when consumers bundle core into their own dist (where runtime
|
|
87
87
|
* `import.meta.url`-based resolution would find the wrong package.json).
|
|
88
88
|
*/
|
|
89
89
|
/** The core library version from package.json (inlined at build time). */
|
|
90
|
-
const CORE_VERSION = '0.
|
|
90
|
+
const CORE_VERSION = '0.3.0';
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
93
|
* Shared file I/O helpers for managed section operations.
|
|
@@ -235,6 +235,12 @@ const AGENTS_MARKERS = {
|
|
|
235
235
|
/** H1 title prepended in the managed block. */
|
|
236
236
|
title: 'Jeeves Platform Agents',
|
|
237
237
|
};
|
|
238
|
+
/** All known marker sets — single source of truth for cross-contamination detection. */
|
|
239
|
+
const ALL_MARKERS = [
|
|
240
|
+
TOOLS_MARKERS,
|
|
241
|
+
SOUL_MARKERS,
|
|
242
|
+
AGENTS_MARKERS,
|
|
243
|
+
];
|
|
238
244
|
/**
|
|
239
245
|
* Regex pattern to extract version stamp from a BEGIN marker comment.
|
|
240
246
|
*
|
|
@@ -583,6 +589,48 @@ function parseManaged(fileContent, markers = TOOLS_MARKERS) {
|
|
|
583
589
|
};
|
|
584
590
|
}
|
|
585
591
|
|
|
592
|
+
/**
|
|
593
|
+
* Strip foreign managed blocks from content.
|
|
594
|
+
*
|
|
595
|
+
* @remarks
|
|
596
|
+
* Prevents cross-contamination by removing managed blocks that belong
|
|
597
|
+
* to other marker sets. For example, when writing TOOLS.md with TOOLS
|
|
598
|
+
* markers, any SOUL or AGENTS managed blocks found in the user content
|
|
599
|
+
* zone are stripped — they don't belong there.
|
|
600
|
+
*
|
|
601
|
+
* @packageDocumentation
|
|
602
|
+
*/
|
|
603
|
+
/**
|
|
604
|
+
* Build a regex that matches an entire managed block (BEGIN marker through END marker).
|
|
605
|
+
*
|
|
606
|
+
* @param markers - The marker set to match.
|
|
607
|
+
* @returns A regex that matches the full block including markers.
|
|
608
|
+
*/
|
|
609
|
+
function buildBlockPattern(markers) {
|
|
610
|
+
const escapedBegin = markers.begin.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
611
|
+
const escapedEnd = markers.end.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
612
|
+
return new RegExp(`\\s*<!--\\s*${escapedBegin}(?:\\s*\\|[^>]*)?\\s*(?:—[^>]*)?\\s*-->[\\s\\S]*?<!--\\s*${escapedEnd}\\s*-->\\s*`, 'g');
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Strip managed blocks belonging to foreign marker sets from content.
|
|
616
|
+
*
|
|
617
|
+
* @param content - The content to clean (typically user content zone).
|
|
618
|
+
* @param currentMarkers - The marker set that owns this file (will NOT be stripped).
|
|
619
|
+
* @returns Content with foreign managed blocks removed.
|
|
620
|
+
*/
|
|
621
|
+
function stripForeignMarkers(content, currentMarkers) {
|
|
622
|
+
let result = content;
|
|
623
|
+
for (const markers of ALL_MARKERS) {
|
|
624
|
+
// Skip the current file's own markers
|
|
625
|
+
if (markers.begin === currentMarkers.begin)
|
|
626
|
+
continue;
|
|
627
|
+
const pattern = buildBlockPattern(markers);
|
|
628
|
+
result = result.replace(pattern, '\n');
|
|
629
|
+
}
|
|
630
|
+
// Clean up multiple blank lines left by removals
|
|
631
|
+
return result.replace(/\n{3,}/g, '\n\n').trim();
|
|
632
|
+
}
|
|
633
|
+
|
|
586
634
|
/**
|
|
587
635
|
* Version-stamp parsing and convergence logic.
|
|
588
636
|
*
|
|
@@ -699,8 +747,8 @@ async function updateManagedSection(filePath, content, options = {}) {
|
|
|
699
747
|
? `# ${markers.title}\n\n${sectionText}`
|
|
700
748
|
: sectionText;
|
|
701
749
|
}
|
|
702
|
-
//
|
|
703
|
-
const userContent = parsed.userContent;
|
|
750
|
+
// Strip foreign managed blocks from user content (cross-contamination fix)
|
|
751
|
+
const userContent = stripForeignMarkers(parsed.userContent, markers);
|
|
704
752
|
const cleanupNeeded = needsCleanup(newManagedBody, userContent);
|
|
705
753
|
// Build the full managed block
|
|
706
754
|
const beginLine = formatBeginMarker(markers.begin, coreVersion);
|
|
@@ -914,11 +962,17 @@ No stranded local branches. Push immediately after commit. A commit that isn't p
|
|
|
914
962
|
|
|
915
963
|
### Check PR State Before Pushing
|
|
916
964
|
|
|
917
|
-
**Before EVERY \`git push\`**,
|
|
965
|
+
**Before EVERY \`git push\`**, run \`gh pr list --head <branch> --repo <repo> --json number,state\` to check whether a PR exists on that branch and whether it's merged.
|
|
966
|
+
|
|
967
|
+
- **No PR exists:** Safe to push.
|
|
968
|
+
- **PR is \`OPEN\`:** Safe to push.
|
|
969
|
+
- **PR is \`MERGED\` or \`CLOSED\`:** **STOP** and report to the user. Do not push to a merged PR branch.
|
|
970
|
+
|
|
971
|
+
This is not optional. It applies to every push, every branch, every time. No judgment call about whether the branch "is a PR branch" — the check is mechanical.
|
|
918
972
|
|
|
919
|
-
|
|
973
|
+
### New PR Over Merged Branch
|
|
920
974
|
|
|
921
|
-
|
|
975
|
+
When a PR has been merged and additional work is needed on the same branch, create a new PR on the **same branch** targeting the same base. Do not create new branches, cherry-pick, or start over. The commits are already there — \`gh pr create --head <existing-branch>\` is the entire operation.
|
|
922
976
|
|
|
923
977
|
## Managed Content Self-Maintenance
|
|
924
978
|
|
|
@@ -954,6 +1008,7 @@ var soulSectionContent = `## Core Truths
|
|
|
954
1008
|
I am a **senior software engineer** first. The persona is style; the engineering discipline is substance.
|
|
955
1009
|
|
|
956
1010
|
What this means in practice:
|
|
1011
|
+
- **Do not execute untested code.** Every mutation script defaults to dry-run mode. The dry-run output is the test — it shows what would happen. Live execution requires an explicit flag. If dry-run is hard to implement, that's a design flaw.
|
|
957
1012
|
- **No cowboy coding.** I don't iterate in production. I don't ship untested changes. I don't treat live systems as scratch pads.
|
|
958
1013
|
- **I follow proper workflows.** Branch, test, review, merge. CI/CD exists for a reason. If there's a pipeline, I use it.
|
|
959
1014
|
- **I resist n00b temptations.** "Let me just quickly…" in prod is how outages happen. I know better.
|
package/package.json
CHANGED