rhachet-roles-bhuild 0.5.9 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contract/cli/give.feedback.d.ts +18 -0
- package/dist/contract/cli/give.feedback.js +59 -0
- package/dist/contract/cli/give.feedback.js.map +1 -0
- package/dist/contract/cli/init.behavior.js +58 -18
- package/dist/contract/cli/init.behavior.js.map +1 -1
- package/dist/domain.objects/BehaviorArtifact.d.ts +32 -0
- package/dist/domain.objects/BehaviorArtifact.js +10 -0
- package/dist/domain.objects/BehaviorArtifact.js.map +1 -0
- package/dist/domain.objects/BehaviorFeedback.d.ts +28 -0
- package/dist/domain.objects/BehaviorFeedback.js +9 -0
- package/dist/domain.objects/BehaviorFeedback.js.map +1 -0
- package/dist/domain.operations/behavior/feedback/computeBehaviorFeedbackName.d.ts +8 -0
- package/dist/domain.operations/behavior/feedback/computeBehaviorFeedbackName.js +13 -0
- package/dist/domain.operations/behavior/feedback/computeBehaviorFeedbackName.js.map +1 -0
- package/dist/domain.operations/behavior/feedback/getBehaviorDirForFeedback.d.ts +17 -0
- package/dist/domain.operations/behavior/feedback/getBehaviorDirForFeedback.js +47 -0
- package/dist/domain.operations/behavior/feedback/getBehaviorDirForFeedback.js.map +1 -0
- package/dist/domain.operations/behavior/feedback/getLatestArtifactByName.d.ts +16 -0
- package/dist/domain.operations/behavior/feedback/getLatestArtifactByName.js +83 -0
- package/dist/domain.operations/behavior/feedback/getLatestArtifactByName.js.map +1 -0
- package/dist/domain.operations/behavior/feedback/giveFeedback.d.ts +17 -0
- package/dist/domain.operations/behavior/feedback/giveFeedback.js +57 -0
- package/dist/domain.operations/behavior/feedback/giveFeedback.js.map +1 -0
- package/dist/domain.operations/behavior/feedback/initFeedbackTemplate.d.ts +10 -0
- package/dist/domain.operations/behavior/feedback/initFeedbackTemplate.js +20 -0
- package/dist/domain.operations/behavior/feedback/initFeedbackTemplate.js.map +1 -0
- package/dist/domain.operations/behavior/init/computeOutputTree.d.ts +9 -0
- package/dist/domain.operations/behavior/init/computeOutputTree.js +35 -0
- package/dist/domain.operations/behavior/init/computeOutputTree.js.map +1 -0
- package/dist/domain.operations/behavior/init/index.d.ts +1 -0
- package/dist/domain.operations/behavior/init/index.js +3 -1
- package/dist/domain.operations/behavior/init/index.js.map +1 -1
- package/dist/domain.operations/behavior/init/templates/.ref.[feedback].v1.[given].by_human.md +1 -1
- package/dist/domain.operations/behavior/render/computeFooterOutput.d.ts +8 -0
- package/dist/domain.operations/behavior/render/computeFooterOutput.js +23 -0
- package/dist/domain.operations/behavior/render/computeFooterOutput.js.map +1 -0
- package/dist/domain.roles/behaver/skills/give.feedback.sh +55 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/infra/shell/OpenerUnavailableError.d.ts +7 -0
- package/dist/infra/shell/OpenerUnavailableError.js +12 -0
- package/dist/infra/shell/OpenerUnavailableError.js.map +1 -0
- package/dist/infra/shell/openFileWithOpener.d.ts +8 -0
- package/dist/infra/shell/openFileWithOpener.js +22 -0
- package/dist/infra/shell/openFileWithOpener.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .what = create a feedback file for a behavior artifact
|
|
3
|
+
*
|
|
4
|
+
* .why = enables structured feedback on any behavior artifact
|
|
5
|
+
* with placeholder substitution and version support
|
|
6
|
+
*
|
|
7
|
+
* usage:
|
|
8
|
+
* give.feedback.sh --against <name> # create feedback for artifact
|
|
9
|
+
* give.feedback.sh --against <name> --behavior <name> # explicit behavior
|
|
10
|
+
* give.feedback.sh --against <name> --version 2 # create v2 feedback
|
|
11
|
+
* give.feedback.sh --against <name> --template <path> # custom template
|
|
12
|
+
*
|
|
13
|
+
* guarantee:
|
|
14
|
+
* - fail-fast if artifact not found
|
|
15
|
+
* - fail-fast if feedback file already exists
|
|
16
|
+
* - fail-fast if template not found
|
|
17
|
+
*/
|
|
18
|
+
export declare const giveFeedback: () => void;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* .what = create a feedback file for a behavior artifact
|
|
4
|
+
*
|
|
5
|
+
* .why = enables structured feedback on any behavior artifact
|
|
6
|
+
* with placeholder substitution and version support
|
|
7
|
+
*
|
|
8
|
+
* usage:
|
|
9
|
+
* give.feedback.sh --against <name> # create feedback for artifact
|
|
10
|
+
* give.feedback.sh --against <name> --behavior <name> # explicit behavior
|
|
11
|
+
* give.feedback.sh --against <name> --version 2 # create v2 feedback
|
|
12
|
+
* give.feedback.sh --against <name> --template <path> # custom template
|
|
13
|
+
*
|
|
14
|
+
* guarantee:
|
|
15
|
+
* - fail-fast if artifact not found
|
|
16
|
+
* - fail-fast if feedback file already exists
|
|
17
|
+
* - fail-fast if template not found
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.giveFeedback = void 0;
|
|
21
|
+
const zod_1 = require("zod");
|
|
22
|
+
const giveFeedback_1 = require("../../domain.operations/behavior/feedback/giveFeedback");
|
|
23
|
+
const cli_1 = require("../../infra/cli");
|
|
24
|
+
// ────────────────────────────────────────────────────────────────────
|
|
25
|
+
// schema
|
|
26
|
+
// ────────────────────────────────────────────────────────────────────
|
|
27
|
+
const schemaOfArgs = zod_1.z.object({
|
|
28
|
+
named: zod_1.z.object({
|
|
29
|
+
// skill-specific args
|
|
30
|
+
against: zod_1.z.string(),
|
|
31
|
+
behavior: zod_1.z.string().optional(),
|
|
32
|
+
version: zod_1.z.coerce.number().optional(),
|
|
33
|
+
template: zod_1.z.string().optional(),
|
|
34
|
+
force: zod_1.z.boolean().optional(),
|
|
35
|
+
// rhachet passthrough args (optional, ignored)
|
|
36
|
+
repo: zod_1.z.string().optional(),
|
|
37
|
+
role: zod_1.z.string().optional(),
|
|
38
|
+
skill: zod_1.z.string().optional(),
|
|
39
|
+
s: zod_1.z.string().optional(),
|
|
40
|
+
}),
|
|
41
|
+
ordered: zod_1.z.array(zod_1.z.string()).default([]),
|
|
42
|
+
});
|
|
43
|
+
// ────────────────────────────────────────────────────────────────────
|
|
44
|
+
// exported CLI entry point
|
|
45
|
+
// ────────────────────────────────────────────────────────────────────
|
|
46
|
+
const giveFeedback = () => {
|
|
47
|
+
const { named } = (0, cli_1.getCliArgs)({ schema: schemaOfArgs });
|
|
48
|
+
const result = (0, giveFeedback_1.giveFeedback)({
|
|
49
|
+
against: named.against,
|
|
50
|
+
behavior: named.behavior,
|
|
51
|
+
version: named.version,
|
|
52
|
+
template: named.template,
|
|
53
|
+
force: named.force,
|
|
54
|
+
});
|
|
55
|
+
console.log(`✓ feedback created: ${result.feedbackFile}`);
|
|
56
|
+
console.log(` against: ${result.artifactFile}`);
|
|
57
|
+
};
|
|
58
|
+
exports.giveFeedback = giveFeedback;
|
|
59
|
+
//# sourceMappingURL=give.feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"give.feedback.js","sourceRoot":"","sources":["../../../src/contract/cli/give.feedback.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;AAEH,6BAAwB;AAExB,wFAAuG;AACvG,wCAA4C;AAE5C,uEAAuE;AACvE,SAAS;AACT,uEAAuE;AAEvE,MAAM,YAAY,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5B,KAAK,EAAE,OAAC,CAAC,MAAM,CAAC;QACd,sBAAsB;QACtB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;QACnB,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACrC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,KAAK,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC7B,+CAA+C;QAC/C,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC5B,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KACzB,CAAC;IACF,OAAO,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACzC,CAAC,CAAC;AAEH,uEAAuE;AACvE,2BAA2B;AAC3B,uEAAuE;AAEhE,MAAM,YAAY,GAAG,GAAS,EAAE;IACrC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAA,gBAAU,EAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAEvD,MAAM,MAAM,GAAG,IAAA,2BAAc,EAAC;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC;AAbW,QAAA,YAAY,gBAavB"}
|
|
@@ -31,7 +31,10 @@ const path_1 = require("path");
|
|
|
31
31
|
const zod_1 = require("zod");
|
|
32
32
|
const bind_1 = require("../../domain.operations/behavior/bind");
|
|
33
33
|
const init_1 = require("../../domain.operations/behavior/init");
|
|
34
|
+
const computeFooterOutput_1 = require("../../domain.operations/behavior/render/computeFooterOutput");
|
|
34
35
|
const cli_1 = require("../../infra/cli");
|
|
36
|
+
const OpenerUnavailableError_1 = require("../../infra/shell/OpenerUnavailableError");
|
|
37
|
+
const openFileWithOpener_1 = require("../../infra/shell/openFileWithOpener");
|
|
35
38
|
// ────────────────────────────────────────────────────────────────────
|
|
36
39
|
// schema
|
|
37
40
|
// ────────────────────────────────────────────────────────────────────
|
|
@@ -40,6 +43,7 @@ const schemaOfArgs = zod_1.z.object({
|
|
|
40
43
|
// skill-specific args
|
|
41
44
|
name: zod_1.z.string(),
|
|
42
45
|
dir: zod_1.z.string().optional(),
|
|
46
|
+
open: zod_1.z.string().optional(),
|
|
43
47
|
// rhachet passthrough args (optional, ignored)
|
|
44
48
|
repo: zod_1.z.string().optional(),
|
|
45
49
|
role: zod_1.z.string().optional(),
|
|
@@ -56,17 +60,19 @@ const initBehavior = () => {
|
|
|
56
60
|
const behaviorName = named.name;
|
|
57
61
|
const rawTargetDir = named.dir ?? process.cwd();
|
|
58
62
|
const context = { cwd: rawTargetDir };
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const bindResult = (0, bind_1.getBranchBehaviorBind)({ branchName: currentBranch }, context);
|
|
63
|
-
if (bindResult.behaviorDir) {
|
|
64
|
-
console.error(`⛈️ error: branch '${currentBranch}' is already bound to: ${(0, path_1.basename)(bindResult.behaviorDir)}`);
|
|
63
|
+
// validate --open has a value if provided
|
|
64
|
+
if (named.open !== undefined && named.open.trim() === '') {
|
|
65
|
+
console.error('⛈️ error: --open requires an editor name');
|
|
65
66
|
console.error('');
|
|
66
|
-
console.error('
|
|
67
|
-
console.error('
|
|
67
|
+
console.error('please specify what editor to open with. for example:');
|
|
68
|
+
console.error(' --open codium');
|
|
69
|
+
console.error(' --open vim');
|
|
70
|
+
console.error(' --open zed');
|
|
71
|
+
console.error(' --open code');
|
|
68
72
|
process.exit(1);
|
|
69
73
|
}
|
|
74
|
+
// get current branch
|
|
75
|
+
const currentBranch = (0, bind_1.getCurrentBranch)({}, context);
|
|
70
76
|
// normalize target dir (trim trailing .behavior)
|
|
71
77
|
const targetDir = rawTargetDir.replace(/\/?\.behavior\/?$/, '');
|
|
72
78
|
// generate isodate in format YYYY_MM_DD
|
|
@@ -74,26 +80,60 @@ const initBehavior = () => {
|
|
|
74
80
|
const isoDate = `${now.getFullYear()}_${String(now.getMonth() + 1).padStart(2, '0')}_${String(now.getDate()).padStart(2, '0')}`;
|
|
75
81
|
// construct behavior directory path (absolute)
|
|
76
82
|
const behaviorDir = (0, path_1.join)(targetDir, '.behavior', `v${isoDate}.${behaviorName}`);
|
|
83
|
+
// check if branch already bound (must be after behaviorDir is computed)
|
|
84
|
+
const bindResult = (0, bind_1.getBranchBehaviorBind)({ branchName: currentBranch }, context);
|
|
85
|
+
if (bindResult.behaviorDir && bindResult.behaviorDir !== behaviorDir) {
|
|
86
|
+
console.error(`⛈️ error: branch '${currentBranch}' is already bound to: ${(0, path_1.basename)(bindResult.behaviorDir)}`);
|
|
87
|
+
console.error('');
|
|
88
|
+
console.error('to create a new behavior, use a new tree:');
|
|
89
|
+
console.error(' git tree set --from main --open <branch-name-new>');
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
77
92
|
// compute relative path from caller's PWD for file contents
|
|
78
93
|
let behaviorDirRel = (0, path_1.join)((0, path_1.relative)(process.cwd(), targetDir), '.behavior', `v${isoDate}.${behaviorName}`);
|
|
79
94
|
// normalize: remove leading ./ if present
|
|
80
95
|
behaviorDirRel = behaviorDirRel.replace(/^\.\//, '');
|
|
81
96
|
// initialize behavior directory with template files
|
|
82
97
|
const result = (0, init_1.initBehaviorDir)({ behaviorDir, behaviorDirRel });
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
98
|
+
// render tree-style output
|
|
99
|
+
const treeOutput = (0, init_1.computeOutputTree)({
|
|
100
|
+
created: result.created,
|
|
101
|
+
kept: result.kept,
|
|
102
|
+
updated: [],
|
|
103
|
+
});
|
|
104
|
+
console.log(treeOutput);
|
|
105
|
+
// compute relative path to wish file
|
|
106
|
+
const wishPathRel = `${behaviorDirRel}/0.wish.md`;
|
|
107
|
+
// try opener if --open is provided (before footer render)
|
|
108
|
+
let openerUsed;
|
|
109
|
+
if (named.open) {
|
|
110
|
+
try {
|
|
111
|
+
(0, openFileWithOpener_1.openFileWithOpener)({ opener: named.open, filePath: wishPathRel });
|
|
112
|
+
openerUsed = named.open;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
if (error instanceof OpenerUnavailableError_1.OpenerUnavailableError) {
|
|
116
|
+
console.log('');
|
|
117
|
+
console.log(`⚠️ ${error.message}`);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
89
123
|
}
|
|
124
|
+
// render footer with wish path (and opener if successful)
|
|
125
|
+
console.log('');
|
|
126
|
+
const footerOutput = (0, computeFooterOutput_1.computeFooterOutput)({ wishPathRel, opener: openerUsed });
|
|
127
|
+
console.log(footerOutput);
|
|
90
128
|
// auto-bind: bind current branch to newly created behavior
|
|
91
129
|
(0, bind_1.setBranchBehaviorBind)({ branchName: currentBranch, behaviorDir, boundBy: 'init.behavior skill' }, context);
|
|
130
|
+
// log branch bind confirmation
|
|
131
|
+
const dim = '\x1b[2m';
|
|
132
|
+
const reset = '\x1b[0m';
|
|
92
133
|
console.log('');
|
|
93
|
-
console.log('
|
|
94
|
-
console.log(` ${
|
|
95
|
-
console.log(
|
|
96
|
-
console.log(`branch '${currentBranch}' bound to: v${isoDate}.${behaviorName}`);
|
|
134
|
+
console.log(`🍄 we'll remember,`);
|
|
135
|
+
console.log(` ├─ branch ${currentBranch} <-> behavior v${isoDate}.${behaviorName}`);
|
|
136
|
+
console.log(` └─ ${dim}branch bound to behavior, to boot via hooks${reset}`);
|
|
97
137
|
};
|
|
98
138
|
exports.initBehavior = initBehavior;
|
|
99
139
|
//# sourceMappingURL=init.behavior.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.behavior.js","sourceRoot":"","sources":["../../../src/contract/cli/init.behavior.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;AAEH,+BAAgD;AAChD,6BAAwB;AAExB,+DAI8C;AAC9C,+
|
|
1
|
+
{"version":3,"file":"init.behavior.js","sourceRoot":"","sources":["../../../src/contract/cli/init.behavior.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DomainLiteral } from 'domain-objects';
|
|
2
|
+
/**
|
|
3
|
+
* .what = a behavior artifact that can be targeted for feedback
|
|
4
|
+
* .why = provides identity and version info for artifact resolution
|
|
5
|
+
*/
|
|
6
|
+
interface BehaviorArtifact {
|
|
7
|
+
/**
|
|
8
|
+
* full path to the artifact file
|
|
9
|
+
*/
|
|
10
|
+
path: string;
|
|
11
|
+
/**
|
|
12
|
+
* artifact name extracted from filename (e.g., 'execution', 'criteria.blackbox')
|
|
13
|
+
*/
|
|
14
|
+
name: string;
|
|
15
|
+
/**
|
|
16
|
+
* version number if present in filename (vX), null otherwise
|
|
17
|
+
*/
|
|
18
|
+
version: number | null;
|
|
19
|
+
/**
|
|
20
|
+
* attempt number if present in filename (iX), null otherwise
|
|
21
|
+
*/
|
|
22
|
+
attempt: number | null;
|
|
23
|
+
/**
|
|
24
|
+
* the base filename without path
|
|
25
|
+
*/
|
|
26
|
+
filename: string;
|
|
27
|
+
}
|
|
28
|
+
declare class BehaviorArtifact extends DomainLiteral<BehaviorArtifact> implements BehaviorArtifact {
|
|
29
|
+
static primary: readonly ["path"];
|
|
30
|
+
static unique: readonly ["path"];
|
|
31
|
+
}
|
|
32
|
+
export { BehaviorArtifact };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BehaviorArtifact = void 0;
|
|
4
|
+
const domain_objects_1 = require("domain-objects");
|
|
5
|
+
class BehaviorArtifact extends domain_objects_1.DomainLiteral {
|
|
6
|
+
}
|
|
7
|
+
exports.BehaviorArtifact = BehaviorArtifact;
|
|
8
|
+
BehaviorArtifact.primary = ['path'];
|
|
9
|
+
BehaviorArtifact.unique = ['path'];
|
|
10
|
+
//# sourceMappingURL=BehaviorArtifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BehaviorArtifact.js","sourceRoot":"","sources":["../../src/domain.objects/BehaviorArtifact.ts"],"names":[],"mappings":";;;AAAA,mDAA+C;AAgC/C,MAAM,gBACJ,SAAQ,8BAA+B;;AAOhC,4CAAgB;AAJT,wBAAO,GAAG,CAAC,MAAM,CAAU,CAAC;AAC5B,uBAAM,GAAG,CAAC,MAAM,CAAU,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { DomainLiteral, type RefByUnique } from 'domain-objects';
|
|
2
|
+
import type { BehaviorArtifact } from './BehaviorArtifact';
|
|
3
|
+
/**
|
|
4
|
+
* .what = a feedback artifact linked to a target behavior artifact
|
|
5
|
+
* .why = tracks the relationship between feedback and its target
|
|
6
|
+
*/
|
|
7
|
+
interface BehaviorFeedback {
|
|
8
|
+
/**
|
|
9
|
+
* full path to the feedback file
|
|
10
|
+
*/
|
|
11
|
+
path: string;
|
|
12
|
+
/**
|
|
13
|
+
* reference to the artifact this feedback targets
|
|
14
|
+
*/
|
|
15
|
+
against: RefByUnique<typeof BehaviorArtifact>;
|
|
16
|
+
/**
|
|
17
|
+
* feedback version (v1, v2, etc.)
|
|
18
|
+
*/
|
|
19
|
+
version: number;
|
|
20
|
+
/**
|
|
21
|
+
* the base filename
|
|
22
|
+
*/
|
|
23
|
+
filename: string;
|
|
24
|
+
}
|
|
25
|
+
declare class BehaviorFeedback extends DomainLiteral<BehaviorFeedback> implements BehaviorFeedback {
|
|
26
|
+
static unique: readonly ["path"];
|
|
27
|
+
}
|
|
28
|
+
export { BehaviorFeedback };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BehaviorFeedback = void 0;
|
|
4
|
+
const domain_objects_1 = require("domain-objects");
|
|
5
|
+
class BehaviorFeedback extends domain_objects_1.DomainLiteral {
|
|
6
|
+
}
|
|
7
|
+
exports.BehaviorFeedback = BehaviorFeedback;
|
|
8
|
+
BehaviorFeedback.unique = ['path'];
|
|
9
|
+
//# sourceMappingURL=BehaviorFeedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BehaviorFeedback.js","sourceRoot":"","sources":["../../src/domain.objects/BehaviorFeedback.ts"],"names":[],"mappings":";;;AAAA,mDAAiE;AA6BjE,MAAM,gBACJ,SAAQ,8BAA+B;;AAMhC,4CAAgB;AAHT,uBAAM,GAAG,CAAC,MAAM,CAAU,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeBehaviorFeedbackName = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* .what = compute the feedback filename for a target artifact
|
|
6
|
+
* .why = centralizes the filename convention logic
|
|
7
|
+
*/
|
|
8
|
+
const computeBehaviorFeedbackName = (input) => {
|
|
9
|
+
// append feedback suffix with version
|
|
10
|
+
return `${input.artifactFileName}.[feedback].v${input.feedbackVersion}.[given].by_human.md`;
|
|
11
|
+
};
|
|
12
|
+
exports.computeBehaviorFeedbackName = computeBehaviorFeedbackName;
|
|
13
|
+
//# sourceMappingURL=computeBehaviorFeedbackName.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"computeBehaviorFeedbackName.js","sourceRoot":"","sources":["../../../../src/domain.operations/behavior/feedback/computeBehaviorFeedbackName.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACI,MAAM,2BAA2B,GAAG,CAAC,KAG3C,EAAU,EAAE;IACX,sCAAsC;IACtC,OAAO,GAAG,KAAK,CAAC,gBAAgB,gBAAgB,KAAK,CAAC,eAAe,sBAAsB,CAAC;AAC9F,CAAC,CAAC;AANW,QAAA,2BAA2B,+BAMtC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .what = resolve the behavior directory for feedback operations
|
|
3
|
+
* .why = supports both bound behavior discovery and explicit --behavior flag
|
|
4
|
+
*
|
|
5
|
+
* .note = priority:
|
|
6
|
+
* - if branch is bound and no flag → use bind
|
|
7
|
+
* - if branch is bound and flag matches → use bind
|
|
8
|
+
* - if branch is bound and flag differs → error (unless --force)
|
|
9
|
+
* - if branch not bound and flag → use flag
|
|
10
|
+
* - if branch not bound and no flag → error
|
|
11
|
+
*/
|
|
12
|
+
export declare const getBehaviorDirForFeedback: (input: {
|
|
13
|
+
behavior?: string;
|
|
14
|
+
force?: boolean;
|
|
15
|
+
}, context?: {
|
|
16
|
+
cwd?: string;
|
|
17
|
+
}) => string;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBehaviorDirForFeedback = void 0;
|
|
4
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
5
|
+
const getBranchBehaviorBind_1 = require("../bind/getBranchBehaviorBind");
|
|
6
|
+
const getBehaviorDir_1 = require("../getBehaviorDir");
|
|
7
|
+
/**
|
|
8
|
+
* .what = resolve the behavior directory for feedback operations
|
|
9
|
+
* .why = supports both bound behavior discovery and explicit --behavior flag
|
|
10
|
+
*
|
|
11
|
+
* .note = priority:
|
|
12
|
+
* - if branch is bound and no flag → use bind
|
|
13
|
+
* - if branch is bound and flag matches → use bind
|
|
14
|
+
* - if branch is bound and flag differs → error (unless --force)
|
|
15
|
+
* - if branch not bound and flag → use flag
|
|
16
|
+
* - if branch not bound and no flag → error
|
|
17
|
+
*/
|
|
18
|
+
const getBehaviorDirForFeedback = (input, context) => {
|
|
19
|
+
const cwd = context?.cwd ?? process.cwd();
|
|
20
|
+
// check for branch bind
|
|
21
|
+
const { behaviorDir: boundDir } = (0, getBranchBehaviorBind_1.getBranchBehaviorBind)({}, { cwd });
|
|
22
|
+
// branch is bound
|
|
23
|
+
if (boundDir) {
|
|
24
|
+
// no explicit flag → use bind
|
|
25
|
+
if (!input.behavior)
|
|
26
|
+
return boundDir;
|
|
27
|
+
// resolve the flag to a directory
|
|
28
|
+
const flagDir = (0, getBehaviorDir_1.getBehaviorDir)({ name: input.behavior, targetDir: cwd });
|
|
29
|
+
// flag matches bind → use bind
|
|
30
|
+
if (flagDir === boundDir)
|
|
31
|
+
return boundDir;
|
|
32
|
+
// flag differs from bind → error unless force
|
|
33
|
+
if (!input.force) {
|
|
34
|
+
throw new helpful_errors_1.BadRequestError(`branch is bound to ${boundDir} but --behavior flag specifies ${flagDir}. use --force to override.`);
|
|
35
|
+
}
|
|
36
|
+
// force override → use flag
|
|
37
|
+
return flagDir;
|
|
38
|
+
}
|
|
39
|
+
// branch not bound, flag provided → use flag
|
|
40
|
+
if (input.behavior) {
|
|
41
|
+
return (0, getBehaviorDir_1.getBehaviorDir)({ name: input.behavior, targetDir: cwd });
|
|
42
|
+
}
|
|
43
|
+
// branch not bound, no flag → error
|
|
44
|
+
throw new helpful_errors_1.BadRequestError('no behavior bound to current branch. use --behavior to specify one.');
|
|
45
|
+
};
|
|
46
|
+
exports.getBehaviorDirForFeedback = getBehaviorDirForFeedback;
|
|
47
|
+
//# sourceMappingURL=getBehaviorDirForFeedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getBehaviorDirForFeedback.js","sourceRoot":"","sources":["../../../../src/domain.operations/behavior/feedback/getBehaviorDirForFeedback.ts"],"names":[],"mappings":";;;AAAA,mDAAiD;AAEjD,yEAAsE;AACtE,sDAAmD;AAEnD;;;;;;;;;;GAUG;AACI,MAAM,yBAAyB,GAAG,CACvC,KAA6C,EAC7C,OAA0B,EAClB,EAAE;IACV,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1C,wBAAwB;IACxB,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,IAAA,6CAAqB,EAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAErE,kBAAkB;IAClB,IAAI,QAAQ,EAAE,CAAC;QACb,8BAA8B;QAC9B,IAAI,CAAC,KAAK,CAAC,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAErC,kCAAkC;QAClC,MAAM,OAAO,GAAG,IAAA,+BAAc,EAAC,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QAEzE,+BAA+B;QAC/B,IAAI,OAAO,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAE1C,8CAA8C;QAC9C,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,IAAI,gCAAe,CACvB,sBAAsB,QAAQ,kCAAkC,OAAO,4BAA4B,CACpG,CAAC;QACJ,CAAC;QAED,4BAA4B;QAC5B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,6CAA6C;IAC7C,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO,IAAA,+BAAc,EAAC,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,oCAAoC;IACpC,MAAM,IAAI,gCAAe,CACvB,qEAAqE,CACtE,CAAC;AACJ,CAAC,CAAC;AAxCW,QAAA,yBAAyB,6BAwCpC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BehaviorArtifact } from '../../../domain.objects/BehaviorArtifact';
|
|
2
|
+
/**
|
|
3
|
+
* .what = resolve the latest artifact by name from a behavior directory
|
|
4
|
+
* .why = enables feedback to target the most recent version of any artifact
|
|
5
|
+
*
|
|
6
|
+
* .note = version precedence:
|
|
7
|
+
* - v3.i2 > v2.i3 (version wins)
|
|
8
|
+
* - v2.i3 > v2.i1 (latest attempt within version)
|
|
9
|
+
* - files with [feedback] in name are excluded
|
|
10
|
+
*/
|
|
11
|
+
export declare const getLatestArtifactByName: (input: {
|
|
12
|
+
behaviorDir: string;
|
|
13
|
+
artifactName: string;
|
|
14
|
+
}, context?: {
|
|
15
|
+
cwd?: string;
|
|
16
|
+
}) => BehaviorArtifact | null;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLatestArtifactByName = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const BehaviorArtifact_1 = require("../../../domain.objects/BehaviorArtifact");
|
|
7
|
+
/**
|
|
8
|
+
* .what = resolve the latest artifact by name from a behavior directory
|
|
9
|
+
* .why = enables feedback to target the most recent version of any artifact
|
|
10
|
+
*
|
|
11
|
+
* .note = version precedence:
|
|
12
|
+
* - v3.i2 > v2.i3 (version wins)
|
|
13
|
+
* - v2.i3 > v2.i1 (latest attempt within version)
|
|
14
|
+
* - files with [feedback] in name are excluded
|
|
15
|
+
*/
|
|
16
|
+
const getLatestArtifactByName = (input, context) => {
|
|
17
|
+
// read directory contents
|
|
18
|
+
const files = (0, fs_1.readdirSync)(input.behaviorDir);
|
|
19
|
+
// build pattern to match artifact files
|
|
20
|
+
// matches: *.<artifactName>[.suffix]*.md where artifactName is followed by . then optional segments
|
|
21
|
+
const artifactPattern = new RegExp(`\\.${escapeRegex(input.artifactName)}(?:\\.[^.]+)*\\.md$`, 'i');
|
|
22
|
+
// parse version/attempt from filename pattern: .v{version}.i{attempt}
|
|
23
|
+
const versionPattern = /\.v(\d+)/;
|
|
24
|
+
const attemptPattern = /\.i(\d+)/;
|
|
25
|
+
// collect artifacts that match the pattern
|
|
26
|
+
const artifactsMatched = [];
|
|
27
|
+
for (const file of files) {
|
|
28
|
+
// skip if doesn't match artifact name pattern
|
|
29
|
+
if (!artifactPattern.test(file))
|
|
30
|
+
continue;
|
|
31
|
+
// skip feedback files
|
|
32
|
+
if (file.includes('[feedback]'))
|
|
33
|
+
continue;
|
|
34
|
+
// skip .src files
|
|
35
|
+
if (file.endsWith('.src'))
|
|
36
|
+
continue;
|
|
37
|
+
// parse version and attempt
|
|
38
|
+
const versionMatch = file.match(versionPattern);
|
|
39
|
+
const attemptMatch = file.match(attemptPattern);
|
|
40
|
+
artifactsMatched.push({
|
|
41
|
+
path: (0, path_1.join)(input.behaviorDir, file),
|
|
42
|
+
name: input.artifactName,
|
|
43
|
+
version: versionMatch?.[1] ? parseInt(versionMatch[1], 10) : null,
|
|
44
|
+
attempt: attemptMatch?.[1] ? parseInt(attemptMatch[1], 10) : null,
|
|
45
|
+
filename: file,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (artifactsMatched.length === 0)
|
|
49
|
+
return null;
|
|
50
|
+
// sort by version desc, then attempt desc
|
|
51
|
+
// null versions/attempts come last
|
|
52
|
+
artifactsMatched.sort((a, b) => {
|
|
53
|
+
// compare versions
|
|
54
|
+
const vA = a.version ?? -1;
|
|
55
|
+
const vB = b.version ?? -1;
|
|
56
|
+
if (vA !== vB)
|
|
57
|
+
return vB - vA;
|
|
58
|
+
// compare attempts
|
|
59
|
+
const iA = a.attempt ?? -1;
|
|
60
|
+
const iB = b.attempt ?? -1;
|
|
61
|
+
return iB - iA;
|
|
62
|
+
});
|
|
63
|
+
// return latest as BehaviorArtifact
|
|
64
|
+
const latest = artifactsMatched[0];
|
|
65
|
+
if (!latest)
|
|
66
|
+
return null;
|
|
67
|
+
return new BehaviorArtifact_1.BehaviorArtifact({
|
|
68
|
+
path: latest.path,
|
|
69
|
+
name: latest.name,
|
|
70
|
+
version: latest.version,
|
|
71
|
+
attempt: latest.attempt,
|
|
72
|
+
filename: latest.filename,
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
exports.getLatestArtifactByName = getLatestArtifactByName;
|
|
76
|
+
/**
|
|
77
|
+
* .what = escape special regex characters in a string
|
|
78
|
+
* .why = enables safe use of artifact names in regex patterns
|
|
79
|
+
*/
|
|
80
|
+
const escapeRegex = (str) => {
|
|
81
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=getLatestArtifactByName.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getLatestArtifactByName.js","sourceRoot":"","sources":["../../../../src/domain.operations/behavior/feedback/getLatestArtifactByName.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .what = create a feedback file for a behavior artifact
|
|
3
|
+
* .why = enables structured feedback on any behavior artifact with placeholder substitution
|
|
4
|
+
*/
|
|
5
|
+
export declare const giveFeedback: (input: {
|
|
6
|
+
against: string;
|
|
7
|
+
behavior?: string;
|
|
8
|
+
version?: number;
|
|
9
|
+
template?: string;
|
|
10
|
+
force?: boolean;
|
|
11
|
+
}, context?: {
|
|
12
|
+
cwd?: string;
|
|
13
|
+
}) => {
|
|
14
|
+
feedbackFile: string;
|
|
15
|
+
artifactFile: string;
|
|
16
|
+
behaviorDir: string;
|
|
17
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.giveFeedback = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const computeBehaviorFeedbackName_1 = require("./computeBehaviorFeedbackName");
|
|
8
|
+
const getBehaviorDirForFeedback_1 = require("./getBehaviorDirForFeedback");
|
|
9
|
+
const getLatestArtifactByName_1 = require("./getLatestArtifactByName");
|
|
10
|
+
const initFeedbackTemplate_1 = require("./initFeedbackTemplate");
|
|
11
|
+
/**
|
|
12
|
+
* .what = create a feedback file for a behavior artifact
|
|
13
|
+
* .why = enables structured feedback on any behavior artifact with placeholder substitution
|
|
14
|
+
*/
|
|
15
|
+
const giveFeedback = (input, context) => {
|
|
16
|
+
const cwd = context?.cwd ?? process.cwd();
|
|
17
|
+
// resolve behavior directory
|
|
18
|
+
const behaviorDir = (0, getBehaviorDirForFeedback_1.getBehaviorDirForFeedback)({ behavior: input.behavior, force: input.force }, { cwd });
|
|
19
|
+
// find latest artifact
|
|
20
|
+
const artifact = (0, getLatestArtifactByName_1.getLatestArtifactByName)({ behaviorDir, artifactName: input.against }, { cwd });
|
|
21
|
+
if (!artifact) {
|
|
22
|
+
throw new helpful_errors_1.BadRequestError(`no artifact found for '${input.against}' in ${behaviorDir}`);
|
|
23
|
+
}
|
|
24
|
+
// compute feedback filename
|
|
25
|
+
const feedbackVersion = input.version ?? 1;
|
|
26
|
+
const feedbackFilename = (0, computeBehaviorFeedbackName_1.computeBehaviorFeedbackName)({
|
|
27
|
+
artifactFileName: artifact.filename,
|
|
28
|
+
feedbackVersion,
|
|
29
|
+
});
|
|
30
|
+
const feedbackPath = (0, path_1.join)(behaviorDir, feedbackFilename);
|
|
31
|
+
// check if feedback file already exists
|
|
32
|
+
if ((0, fs_1.existsSync)(feedbackPath)) {
|
|
33
|
+
throw new helpful_errors_1.BadRequestError(`feedback file already exists: ${feedbackFilename}. use --version ${feedbackVersion + 1} to create a new version.`);
|
|
34
|
+
}
|
|
35
|
+
// resolve template path
|
|
36
|
+
const templatePath = input.template ??
|
|
37
|
+
(0, path_1.join)(behaviorDir, '.ref.[feedback].v1.[given].by_human.md');
|
|
38
|
+
if (!(0, fs_1.existsSync)(templatePath)) {
|
|
39
|
+
throw new helpful_errors_1.BadRequestError(`template not found: ${templatePath}`);
|
|
40
|
+
}
|
|
41
|
+
// compute relative behavior directory path
|
|
42
|
+
const behaviorDirRel = (0, path_1.relative)(cwd, behaviorDir);
|
|
43
|
+
// init feedback file from template
|
|
44
|
+
(0, initFeedbackTemplate_1.initFeedbackTemplate)({
|
|
45
|
+
templatePath,
|
|
46
|
+
targetPath: feedbackPath,
|
|
47
|
+
artifactFileName: artifact.filename,
|
|
48
|
+
behaviorDirRel,
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
feedbackFile: feedbackPath,
|
|
52
|
+
artifactFile: artifact.path,
|
|
53
|
+
behaviorDir,
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
exports.giveFeedback = giveFeedback;
|
|
57
|
+
//# sourceMappingURL=giveFeedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"giveFeedback.js","sourceRoot":"","sources":["../../../../src/domain.operations/behavior/feedback/giveFeedback.ts"],"names":[],"mappings":";;;AAAA,2BAAgC;AAChC,mDAAiD;AACjD,+BAAsC;AAEtC,+EAA4E;AAC5E,2EAAwE;AACxE,uEAAoE;AACpE,iEAA8D;AAE9D;;;GAGG;AACI,MAAM,YAAY,GAAG,CAC1B,KAMC,EACD,OAA0B,EAC2C,EAAE;IACvE,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1C,6BAA6B;IAC7B,MAAM,WAAW,GAAG,IAAA,qDAAyB,EAC3C,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAChD,EAAE,GAAG,EAAE,CACR,CAAC;IAEF,uBAAuB;IACvB,MAAM,QAAQ,GAAG,IAAA,iDAAuB,EACtC,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,CAAC,OAAO,EAAE,EAC5C,EAAE,GAAG,EAAE,CACR,CAAC;IACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,gCAAe,CACvB,0BAA0B,KAAK,CAAC,OAAO,QAAQ,WAAW,EAAE,CAC7D,CAAC;IACJ,CAAC;IAED,4BAA4B;IAC5B,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;IAC3C,MAAM,gBAAgB,GAAG,IAAA,yDAA2B,EAAC;QACnD,gBAAgB,EAAE,QAAQ,CAAC,QAAQ;QACnC,eAAe;KAChB,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAEzD,wCAAwC;IACxC,IAAI,IAAA,eAAU,EAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,gCAAe,CACvB,iCAAiC,gBAAgB,mBAAmB,eAAe,GAAG,CAAC,2BAA2B,CACnH,CAAC;IACJ,CAAC;IAED,wBAAwB;IACxB,MAAM,YAAY,GAChB,KAAK,CAAC,QAAQ;QACd,IAAA,WAAI,EAAC,WAAW,EAAE,wCAAwC,CAAC,CAAC;IAC9D,IAAI,CAAC,IAAA,eAAU,EAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,gCAAe,CAAC,uBAAuB,YAAY,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,2CAA2C;IAC3C,MAAM,cAAc,GAAG,IAAA,eAAQ,EAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAElD,mCAAmC;IACnC,IAAA,2CAAoB,EAAC;QACnB,YAAY;QACZ,UAAU,EAAE,YAAY;QACxB,gBAAgB,EAAE,QAAQ,CAAC,QAAQ;QACnC,cAAc;KACf,CAAC,CAAC;IAEH,OAAO;QACL,YAAY,EAAE,YAAY;QAC1B,YAAY,EAAE,QAAQ,CAAC,IAAI;QAC3B,WAAW;KACZ,CAAC;AACJ,CAAC,CAAC;AApEW,QAAA,YAAY,gBAoEvB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .what = initialize a feedback file from a template with placeholder substitution
|
|
3
|
+
* .why = enables consistent feedback file creation with behavior-specific values
|
|
4
|
+
*/
|
|
5
|
+
export declare const initFeedbackTemplate: (input: {
|
|
6
|
+
templatePath: string;
|
|
7
|
+
targetPath: string;
|
|
8
|
+
artifactFileName: string;
|
|
9
|
+
behaviorDirRel: string;
|
|
10
|
+
}) => void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initFeedbackTemplate = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
/**
|
|
6
|
+
* .what = initialize a feedback file from a template with placeholder substitution
|
|
7
|
+
* .why = enables consistent feedback file creation with behavior-specific values
|
|
8
|
+
*/
|
|
9
|
+
const initFeedbackTemplate = (input) => {
|
|
10
|
+
// read template content
|
|
11
|
+
const templateContent = (0, fs_1.readFileSync)(input.templatePath, 'utf-8');
|
|
12
|
+
// replace placeholders with actual values
|
|
13
|
+
const content = templateContent
|
|
14
|
+
.replace(/\$BEHAVIOR_REF_NAME/g, input.artifactFileName)
|
|
15
|
+
.replace(/\$BEHAVIOR_DIR_REL/g, input.behaviorDirRel);
|
|
16
|
+
// write to target path
|
|
17
|
+
(0, fs_1.writeFileSync)(input.targetPath, content, 'utf-8');
|
|
18
|
+
};
|
|
19
|
+
exports.initFeedbackTemplate = initFeedbackTemplate;
|
|
20
|
+
//# sourceMappingURL=initFeedbackTemplate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initFeedbackTemplate.js","sourceRoot":"","sources":["../../../../src/domain.operations/behavior/feedback/initFeedbackTemplate.ts"],"names":[],"mappings":";;;AAAA,2BAAiD;AAEjD;;;GAGG;AACI,MAAM,oBAAoB,GAAG,CAAC,KAKpC,EAAQ,EAAE;IACT,wBAAwB;IACxB,MAAM,eAAe,GAAG,IAAA,iBAAY,EAAC,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAElE,0CAA0C;IAC1C,MAAM,OAAO,GAAG,eAAe;SAC5B,OAAO,CAAC,sBAAsB,EAAE,KAAK,CAAC,gBAAgB,CAAC;SACvD,OAAO,CAAC,qBAAqB,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAExD,uBAAuB;IACvB,IAAA,kBAAa,EAAC,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC,CAAC;AAhBW,QAAA,oBAAoB,wBAgB/B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .what = compute tree-style output for behavior init file actions
|
|
3
|
+
* .why = vibed, scannable output that shows file actions clearly
|
|
4
|
+
*/
|
|
5
|
+
export declare const computeOutputTree: (input: {
|
|
6
|
+
created: string[];
|
|
7
|
+
kept: string[];
|
|
8
|
+
updated: string[];
|
|
9
|
+
}) => string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeOutputTree = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* .what = compute tree-style output for behavior init file actions
|
|
6
|
+
* .why = vibed, scannable output that shows file actions clearly
|
|
7
|
+
*/
|
|
8
|
+
const computeOutputTree = (input) => {
|
|
9
|
+
// define symbols for each action type
|
|
10
|
+
const symbolCreated = '+';
|
|
11
|
+
const symbolKept = '✓';
|
|
12
|
+
const symbolUpdated = '↻';
|
|
13
|
+
// combine all files with their symbols
|
|
14
|
+
const entries = [
|
|
15
|
+
...input.created.map((file) => ({ file, symbol: symbolCreated })),
|
|
16
|
+
...input.kept.map((file) => ({ file, symbol: symbolKept })),
|
|
17
|
+
...input.updated.map((file) => ({ file, symbol: symbolUpdated })),
|
|
18
|
+
];
|
|
19
|
+
// sort alphabetically by filename
|
|
20
|
+
entries.sort((a, b) => a.file.localeCompare(b.file));
|
|
21
|
+
// build header
|
|
22
|
+
const header = '🦫 oh, behave!';
|
|
23
|
+
// handle empty case
|
|
24
|
+
if (entries.length === 0)
|
|
25
|
+
return header;
|
|
26
|
+
// build tree lines
|
|
27
|
+
const lines = entries.map((entry, index) => {
|
|
28
|
+
const isLast = index === entries.length - 1;
|
|
29
|
+
const branch = isLast ? '└─' : '├─';
|
|
30
|
+
return ` ${branch} ${entry.symbol} ${entry.file}`;
|
|
31
|
+
});
|
|
32
|
+
return [header, ...lines].join('\n');
|
|
33
|
+
};
|
|
34
|
+
exports.computeOutputTree = computeOutputTree;
|
|
35
|
+
//# sourceMappingURL=computeOutputTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"computeOutputTree.js","sourceRoot":"","sources":["../../../../src/domain.operations/behavior/init/computeOutputTree.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACI,MAAM,iBAAiB,GAAG,CAAC,KAIjC,EAAU,EAAE;IACX,sCAAsC;IACtC,MAAM,aAAa,GAAG,GAAG,CAAC;IAC1B,MAAM,UAAU,GAAG,GAAG,CAAC;IACvB,MAAM,aAAa,GAAG,GAAG,CAAC;IAE1B,uCAAuC;IACvC,MAAM,OAAO,GAA4C;QACvD,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;QACjE,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAC3D,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;KAClE,CAAC;IAEF,kCAAkC;IAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAErD,eAAe;IACf,MAAM,MAAM,GAAG,gBAAgB,CAAC;IAEhC,oBAAoB;IACpB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAExC,mBAAmB;IACnB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACpC,OAAO,MAAM,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC,CAAC;AAlCW,QAAA,iBAAiB,qBAkC5B"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.initBehaviorDir = void 0;
|
|
3
|
+
exports.initBehaviorDir = exports.computeOutputTree = void 0;
|
|
4
|
+
var computeOutputTree_1 = require("./computeOutputTree");
|
|
5
|
+
Object.defineProperty(exports, "computeOutputTree", { enumerable: true, get: function () { return computeOutputTree_1.computeOutputTree; } });
|
|
4
6
|
var initBehaviorDir_1 = require("./initBehaviorDir");
|
|
5
7
|
Object.defineProperty(exports, "initBehaviorDir", { enumerable: true, get: function () { return initBehaviorDir_1.initBehaviorDir; } });
|
|
6
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/domain.operations/behavior/init/index.ts"],"names":[],"mappings":";;;AAAA,qDAAoD;AAA3C,kHAAA,eAAe,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/domain.operations/behavior/init/index.ts"],"names":[],"mappings":";;;AAAA,yDAAwD;AAA/C,sHAAA,iBAAiB,OAAA;AAC1B,qDAAoD;AAA3C,kHAAA,eAAe,OAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeFooterOutput = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* .what = compute footer output with relative wish path
|
|
6
|
+
* .why = easy-to-copy path for open of the wish file
|
|
7
|
+
*/
|
|
8
|
+
const computeFooterOutput = (input) => {
|
|
9
|
+
const dim = '\x1b[2m';
|
|
10
|
+
const reset = '\x1b[0m';
|
|
11
|
+
// build output lines
|
|
12
|
+
const lines = [`🌲 go on then,`, ` ├─ ${input.wishPathRel}`];
|
|
13
|
+
// add opener line or tip based on whether opener was used
|
|
14
|
+
if (input.opener) {
|
|
15
|
+
lines.push(` └─ ${dim}opened in ${input.opener}${reset}`);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
lines.push(` └─ ${dim}tip: use --open to open the wish automatically${reset}`);
|
|
19
|
+
}
|
|
20
|
+
return lines.join('\n');
|
|
21
|
+
};
|
|
22
|
+
exports.computeFooterOutput = computeFooterOutput;
|
|
23
|
+
//# sourceMappingURL=computeFooterOutput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"computeFooterOutput.js","sourceRoot":"","sources":["../../../../src/domain.operations/behavior/render/computeFooterOutput.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACI,MAAM,mBAAmB,GAAG,CAAC,KAGnC,EAAU,EAAE;IACX,MAAM,GAAG,GAAG,SAAS,CAAC;IACtB,MAAM,KAAK,GAAG,SAAS,CAAC;IAExB,qBAAqB;IACrB,MAAM,KAAK,GAAG,CAAC,gBAAgB,EAAE,SAAS,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAE/D,0DAA0D;IAC1D,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,aAAa,KAAK,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC;IAC9D,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CACR,SAAS,GAAG,iDAAiD,KAAK,EAAE,CACrE,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC,CAAC;AApBW,QAAA,mBAAmB,uBAoB9B"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
######################################################################
|
|
3
|
+
# .what = generate a feedback file for a behavior artifact
|
|
4
|
+
#
|
|
5
|
+
# .why = enables structured feedback on any behavior artifact
|
|
6
|
+
# - creates feedback files linked to target artifacts
|
|
7
|
+
# - supports versioned feedback (v1, v2, etc.)
|
|
8
|
+
# - replaces template placeholders with artifact references
|
|
9
|
+
#
|
|
10
|
+
# .when = use this skill when you need to:
|
|
11
|
+
# - provide feedback on an execution artifact
|
|
12
|
+
# - review criteria, blueprint, or research artifacts
|
|
13
|
+
# - create structured response templates for human review
|
|
14
|
+
#
|
|
15
|
+
# .how = thin dispatcher to TypeScript implementation
|
|
16
|
+
#
|
|
17
|
+
# .args:
|
|
18
|
+
# --against <name> (required) artifact name to target
|
|
19
|
+
# e.g., execution, criteria.blackbox, wish, blueprint
|
|
20
|
+
# --behavior <name> (optional) behavior directory name
|
|
21
|
+
# required if branch is not bound to a behavior
|
|
22
|
+
# --version <N> (optional) feedback version number (default: 1)
|
|
23
|
+
# --template <path> (optional) custom template file path
|
|
24
|
+
# --force (optional) override bind mismatch
|
|
25
|
+
#
|
|
26
|
+
# .examples:
|
|
27
|
+
# # generate feedback for latest execution artifact (branch must be bound)
|
|
28
|
+
# npx rhachet run --skill give.feedback --against execution
|
|
29
|
+
#
|
|
30
|
+
# # generate feedback for criteria.blackbox with explicit behavior
|
|
31
|
+
# npx rhachet run --skill give.feedback --against criteria.blackbox --behavior give-feedback
|
|
32
|
+
#
|
|
33
|
+
# # generate v2 feedback on same artifact
|
|
34
|
+
# npx rhachet run --skill give.feedback --against execution --version 2
|
|
35
|
+
#
|
|
36
|
+
# # use custom template
|
|
37
|
+
# npx rhachet run --skill give.feedback --against wish --template ./my-template.md
|
|
38
|
+
#
|
|
39
|
+
# # override bind mismatch with --force
|
|
40
|
+
# npx rhachet run --skill give.feedback --against blueprint --behavior other-feature --force
|
|
41
|
+
#
|
|
42
|
+
# .output:
|
|
43
|
+
# - creates: ${behaviorDir}/${artifactFileName}.[feedback].v${version}.[given].by_human.md
|
|
44
|
+
# - logs: feedback file path and target artifact to stdout
|
|
45
|
+
#
|
|
46
|
+
# .errors:
|
|
47
|
+
# - no artifact found: shows glob pattern used
|
|
48
|
+
# - feedback exists: prevents overwrite, suggests --version
|
|
49
|
+
# - template not found: indicates template path needed
|
|
50
|
+
# - bind mismatch: suggests --force to override
|
|
51
|
+
######################################################################
|
|
52
|
+
|
|
53
|
+
set -euo pipefail
|
|
54
|
+
|
|
55
|
+
exec npx tsx -e "import('rhachet-roles-bhuild').then(m => m.cli.giveFeedback())" -- "$@"
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -20,12 +20,14 @@ __exportStar(require("./contract/sdk"), exports);
|
|
|
20
20
|
const bind_behavior_1 = require("./contract/cli/bind.behavior");
|
|
21
21
|
const boot_behavior_1 = require("./contract/cli/boot.behavior");
|
|
22
22
|
const decompose_behavior_1 = require("./contract/cli/decompose.behavior");
|
|
23
|
+
const give_feedback_1 = require("./contract/cli/give.feedback");
|
|
23
24
|
const init_behavior_1 = require("./contract/cli/init.behavior");
|
|
24
25
|
const review_behavior_1 = require("./contract/cli/review.behavior");
|
|
25
26
|
exports.cli = {
|
|
26
27
|
bindBehavior: bind_behavior_1.bindBehavior,
|
|
27
28
|
bootBehavior: boot_behavior_1.bootBehavior,
|
|
28
29
|
decomposeBehavior: decompose_behavior_1.decomposeBehavior,
|
|
30
|
+
giveFeedback: give_feedback_1.giveFeedback,
|
|
29
31
|
initBehavior: init_behavior_1.initBehavior,
|
|
30
32
|
reviewBehavior: review_behavior_1.reviewBehavior,
|
|
31
33
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iDAA+B;AAE/B,+CAA+C;AAC/C,gEAA4D;AAC5D,gEAA4D;AAC5D,0EAAsE;AACtE,gEAA4D;AAC5D,oEAAgE;AAEnD,QAAA,GAAG,GAAG;IACjB,YAAY,EAAZ,4BAAY;IACZ,YAAY,EAAZ,4BAAY;IACZ,iBAAiB,EAAjB,sCAAiB;IACjB,YAAY,EAAZ,4BAAY;IACZ,cAAc,EAAd,gCAAc;CACf,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iDAA+B;AAE/B,+CAA+C;AAC/C,gEAA4D;AAC5D,gEAA4D;AAC5D,0EAAsE;AACtE,gEAA4D;AAC5D,gEAA4D;AAC5D,oEAAgE;AAEnD,QAAA,GAAG,GAAG;IACjB,YAAY,EAAZ,4BAAY;IACZ,YAAY,EAAZ,4BAAY;IACZ,iBAAiB,EAAjB,sCAAiB;IACjB,YAAY,EAAZ,4BAAY;IACZ,YAAY,EAAZ,4BAAY;IACZ,cAAc,EAAd,gCAAc;CACf,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { HelpfulError } from 'helpful-errors';
|
|
2
|
+
/**
|
|
3
|
+
* .what = error thrown when opener command is unavailable or fails
|
|
4
|
+
* .why = named error for control flow - orchestrator catches this specifically
|
|
5
|
+
*/
|
|
6
|
+
export declare class OpenerUnavailableError extends HelpfulError {
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OpenerUnavailableError = void 0;
|
|
4
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
5
|
+
/**
|
|
6
|
+
* .what = error thrown when opener command is unavailable or fails
|
|
7
|
+
* .why = named error for control flow - orchestrator catches this specifically
|
|
8
|
+
*/
|
|
9
|
+
class OpenerUnavailableError extends helpful_errors_1.HelpfulError {
|
|
10
|
+
}
|
|
11
|
+
exports.OpenerUnavailableError = OpenerUnavailableError;
|
|
12
|
+
//# sourceMappingURL=OpenerUnavailableError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenerUnavailableError.js","sourceRoot":"","sources":["../../../src/infra/shell/OpenerUnavailableError.ts"],"names":[],"mappings":";;;AAAA,mDAA8C;AAE9C;;;GAGG;AACH,MAAa,sBAAuB,SAAQ,6BAAY;CAAG;AAA3D,wDAA2D"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.openFileWithOpener = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const OpenerUnavailableError_1 = require("./OpenerUnavailableError");
|
|
6
|
+
/**
|
|
7
|
+
* .what = open a file with specified editor/opener
|
|
8
|
+
* .why = streamline user workflow by auto-open of wish file
|
|
9
|
+
*/
|
|
10
|
+
const openFileWithOpener = (input) => {
|
|
11
|
+
// build command with quoted path for safety
|
|
12
|
+
const command = `${input.opener} "${input.filePath}"`;
|
|
13
|
+
// execute and let errors propagate as OpenerUnavailableError
|
|
14
|
+
try {
|
|
15
|
+
(0, child_process_1.execSync)(command, { stdio: 'inherit' });
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
throw new OpenerUnavailableError_1.OpenerUnavailableError(`opener '${input.opener}' unavailable or failed`, { cause: error instanceof Error ? error : undefined });
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
exports.openFileWithOpener = openFileWithOpener;
|
|
22
|
+
//# sourceMappingURL=openFileWithOpener.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openFileWithOpener.js","sourceRoot":"","sources":["../../../src/infra/shell/openFileWithOpener.ts"],"names":[],"mappings":";;;AAAA,iDAAyC;AAEzC,qEAAkE;AAElE;;;GAGG;AACI,MAAM,kBAAkB,GAAG,CAAC,KAGlC,EAAQ,EAAE;IACT,4CAA4C;IAC5C,MAAM,OAAO,GAAG,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,QAAQ,GAAG,CAAC;IAEtD,6DAA6D;IAC7D,IAAI,CAAC;QACH,IAAA,wBAAQ,EAAC,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,+CAAsB,CAC9B,WAAW,KAAK,CAAC,MAAM,yBAAyB,EAChD,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CACtD,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAhBW,QAAA,kBAAkB,sBAgB7B"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "rhachet-roles-bhuild",
|
|
3
3
|
"author": "ehmpathy",
|
|
4
4
|
"description": "roles for building resilient systems, via rhachet",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.6.0",
|
|
6
6
|
"repository": "ehmpathy/rhachet-roles-bhuild",
|
|
7
7
|
"homepage": "https://github.com/ehmpathy/rhachet-roles-bhuild",
|
|
8
8
|
"keywords": [
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"domain-objects": "0.31.9",
|
|
58
58
|
"helpful-errors": "1.5.3",
|
|
59
|
-
"rhachet-roles-bhrain": "0.5.
|
|
59
|
+
"rhachet-roles-bhrain": "0.5.9",
|
|
60
60
|
"test-fns": "1.7.2",
|
|
61
61
|
"zod": "4.3.4"
|
|
62
62
|
},
|