@tangle-network/agent-profile-materialize 0.17.0 → 0.17.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/dist/execution-controls.js +3 -3
- package/dist/harness.d.ts +33 -9
- package/dist/harness.js +75 -12
- package/dist/mcp.js +3 -2
- package/dist/plan-types.d.ts +12 -8
- package/dist/profile-plan.js +2 -2
- package/dist/profile-prompt.js +3 -3
- package/dist/workspace-apply.js +14 -5
- package/package.json +1 -1
|
@@ -35,8 +35,8 @@ export function materializeExecutionControls(h, tools, permissions, modes, plan,
|
|
|
35
35
|
const nativeTools = mapSupportedBooleanEntries(enforceableTools, openCodeToolName, (name) => unsupported("tools", `opencode: no verified native tool mapping for "${name}"`), "opencode tool");
|
|
36
36
|
const nativePermissions = mapSupportedPermissionEntries(enforceablePermissions, openCodePermissionName, (name) => unsupported("permissions", `opencode: no verified native permission mapping for "${name}"`), "opencode permission");
|
|
37
37
|
if (enforceableTools.length > 0 || permissionEntries.length > 0) {
|
|
38
|
-
add(
|
|
39
|
-
$schema:
|
|
38
|
+
add(OPENCODE_CONFIG_FILE, serializeWorkspacePlanJson({
|
|
39
|
+
$schema: OPENCODE_CONFIG_SCHEMA,
|
|
40
40
|
...(nativeTools.length > 0
|
|
41
41
|
? { tools: Object.fromEntries(nativeTools) }
|
|
42
42
|
: {}),
|
|
@@ -180,7 +180,7 @@ function piExecutionControlExtensionSource(enabledTools, excludedTools) {
|
|
|
180
180
|
}
|
|
181
181
|
import { resolveNativeWebTools } from "@tangle-network/agent-interface";
|
|
182
182
|
import { claudePermissionRules, claudeToolName, mapSupportedBooleanEntries, mapSupportedPermissionEntries, normalizedControlName, openCodePermissionName, openCodeToolName, PI_EXECUTION_CONTROL_EXTENSION_PATH, permissionAllowsEverything, piToolId, sealClaudePermissionRules, } from "./control-maps.js";
|
|
183
|
-
import { CLAUDE_SETTINGS_PATH } from "./harness.js";
|
|
183
|
+
import { CLAUDE_SETTINGS_PATH, OPENCODE_CONFIG_FILE, OPENCODE_CONFIG_SCHEMA, } from "./harness.js";
|
|
184
184
|
import { registerClaudeSettings } from "./hooks.js";
|
|
185
185
|
import { serializeWorkspacePlanJson } from "./plan-json.js";
|
|
186
186
|
import { compareStrings } from "./workspace-files.js";
|
package/dist/harness.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export declare function isMaterializerHarness(harness: string): harness is Harne
|
|
|
4
4
|
export declare function assertMaterializerHarness(harness: string): asserts harness is HarnessId;
|
|
5
5
|
export declare const CODEX_SYSTEM_PROMPT_FILE = ".codex/system-prompt.md";
|
|
6
6
|
export declare const OPENCODE_APPEND_SYSTEM_PROMPT_FILE = ".opencode/agent-system-prompt.md";
|
|
7
|
+
export declare const OPENCODE_CONFIG_FILE = "opencode.json";
|
|
8
|
+
export declare const OPENCODE_CONFIG_SCHEMA = "https://opencode.ai/config.json";
|
|
7
9
|
export declare const OPENCODE_PRIMARY_AGENT_PREFIX = "tangle-profile-";
|
|
8
10
|
export declare const CLAUDE_SETTINGS_PATH = ".tangle/claude-settings.json";
|
|
9
11
|
export declare function harnessAutoLoadsContextFile(harness: HarnessId): boolean;
|
|
@@ -38,30 +40,52 @@ export declare function appendSystemPromptRefusal(harness: HarnessId): string;
|
|
|
38
40
|
/** Project context file each harness actually reads from cwd. NEVER a constant. */
|
|
39
41
|
export declare const CONTEXT_FILE: Record<HarnessId, string>;
|
|
40
42
|
/**
|
|
41
|
-
* The paths
|
|
42
|
-
* {@link PlanFile.ownership}.
|
|
43
|
+
* The paths a profile resource may never mount.
|
|
43
44
|
*
|
|
44
45
|
* Codex names no system-prompt file of its own — `model_instructions_file`
|
|
45
46
|
* takes whatever path it is given — and opencode names none either, since it
|
|
46
47
|
* reads exactly the files its config lists. All three names below were chosen
|
|
47
48
|
* here, so a file already at one of them is this materializer's own output from
|
|
48
|
-
* an earlier application into the same workspace
|
|
49
|
+
* an earlier application into the same workspace, and a mount there could not
|
|
50
|
+
* survive the next application.
|
|
49
51
|
*
|
|
50
52
|
* That is an inference from the path name, not verified provenance: nothing
|
|
51
53
|
* checks the existing bytes are prior materializer output, so a workspace that
|
|
52
54
|
* carried a foreign file at one of these invented names is overwritten on the
|
|
53
55
|
* first application. Accepted cost of stateless multi-turn re-application,
|
|
54
56
|
* bounded by the names being ones no harness or user convention uses.
|
|
57
|
+
*/
|
|
58
|
+
export declare const MATERIALIZER_RESERVED_PATHS: ReadonlySet<string>;
|
|
59
|
+
/**
|
|
60
|
+
* The paths whose generated content is wholly this package's output, per
|
|
61
|
+
* {@link PlanFile.ownership}: the reserved names plus `opencode.json`, which
|
|
62
|
+
* carries only the registrations this package generates from the profile.
|
|
63
|
+
*
|
|
64
|
+
* `opencode.json` is a documented name a user repository can carry, so the
|
|
65
|
+
* name alone proves nothing and a profile resource may still mount it. An
|
|
66
|
+
* existing file there is replaced only when {@link isMaterializerOutput}
|
|
67
|
+
* recognizes its bytes as this package's own earlier output.
|
|
55
68
|
*
|
|
56
69
|
* Deliberately absent: `.gemini/system.md` (gemini's own documented name),
|
|
57
|
-
* `GEMINI.md`, `CLAUDE.md`, `AGENTS.md
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* `instructions[]` membership between turns of one workspace refuses loudly
|
|
61
|
-
* (the consolidated config no longer matches byte-for-byte) rather than
|
|
62
|
-
* replacing a possibly user-authored config.
|
|
70
|
+
* `GEMINI.md`, `CLAUDE.md`, `AGENTS.md`. A user's repository can carry any of
|
|
71
|
+
* those with content this package cannot tell from its own, and clobbering
|
|
72
|
+
* one is worse than refusing the turn.
|
|
63
73
|
*/
|
|
64
74
|
export declare const MATERIALIZER_OWNED_PATHS: ReadonlySet<string>;
|
|
75
|
+
/** The top-level keys this package writes into `opencode.json`. */
|
|
76
|
+
export declare const OPENCODE_CONFIG_KEYS: ReadonlySet<string>;
|
|
77
|
+
/**
|
|
78
|
+
* Whether the file already at owned path `relPath` is this package's own
|
|
79
|
+
* earlier output. A reserved name proves that by itself, so `content` is read
|
|
80
|
+
* only for `opencode.json`; `undefined` content means no regular file is there.
|
|
81
|
+
*
|
|
82
|
+
* An `opencode.json` this package wrote holds the opencode schema id, only the
|
|
83
|
+
* keys this package writes, and only instruction paths this package invented.
|
|
84
|
+
* A user config that holds nothing else is indistinguishable from that output
|
|
85
|
+
* and is replaced too; a config with any other key, or with an instruction path
|
|
86
|
+
* of the user's own, is refused.
|
|
87
|
+
*/
|
|
88
|
+
export declare function isMaterializerOutput(relPath: string, content: () => string | undefined): boolean;
|
|
65
89
|
/**
|
|
66
90
|
* cwd-relative native skill dir per harness, or null if the harness has no
|
|
67
91
|
* cwd skill primitive (skills live in a user/global dir the workspace plan
|
package/dist/harness.js
CHANGED
|
@@ -21,6 +21,8 @@ export function assertMaterializerHarness(harness) {
|
|
|
21
21
|
}
|
|
22
22
|
export const CODEX_SYSTEM_PROMPT_FILE = ".codex/system-prompt.md";
|
|
23
23
|
export const OPENCODE_APPEND_SYSTEM_PROMPT_FILE = ".opencode/agent-system-prompt.md";
|
|
24
|
+
export const OPENCODE_CONFIG_FILE = "opencode.json";
|
|
25
|
+
export const OPENCODE_CONFIG_SCHEMA = "https://opencode.ai/config.json";
|
|
24
26
|
export const OPENCODE_PRIMARY_AGENT_PREFIX = "tangle-profile-";
|
|
25
27
|
export const CLAUDE_SETTINGS_PATH = ".tangle/claude-settings.json";
|
|
26
28
|
export function harnessAutoLoadsContextFile(harness) {
|
|
@@ -101,34 +103,95 @@ export const CONTEXT_FILE = {
|
|
|
101
103
|
openclaw: "AGENTS.md",
|
|
102
104
|
};
|
|
103
105
|
/**
|
|
104
|
-
* The paths
|
|
105
|
-
* {@link PlanFile.ownership}.
|
|
106
|
+
* The paths a profile resource may never mount.
|
|
106
107
|
*
|
|
107
108
|
* Codex names no system-prompt file of its own — `model_instructions_file`
|
|
108
109
|
* takes whatever path it is given — and opencode names none either, since it
|
|
109
110
|
* reads exactly the files its config lists. All three names below were chosen
|
|
110
111
|
* here, so a file already at one of them is this materializer's own output from
|
|
111
|
-
* an earlier application into the same workspace
|
|
112
|
+
* an earlier application into the same workspace, and a mount there could not
|
|
113
|
+
* survive the next application.
|
|
112
114
|
*
|
|
113
115
|
* That is an inference from the path name, not verified provenance: nothing
|
|
114
116
|
* checks the existing bytes are prior materializer output, so a workspace that
|
|
115
117
|
* carried a foreign file at one of these invented names is overwritten on the
|
|
116
118
|
* first application. Accepted cost of stateless multi-turn re-application,
|
|
117
119
|
* bounded by the names being ones no harness or user convention uses.
|
|
118
|
-
*
|
|
119
|
-
* Deliberately absent: `.gemini/system.md` (gemini's own documented name),
|
|
120
|
-
* `GEMINI.md`, `CLAUDE.md`, `AGENTS.md`, `opencode.json`. A user's repository
|
|
121
|
-
* can carry any of those, and clobbering one is worse than refusing the turn.
|
|
122
|
-
* For `opencode.json` this means a profile change that alters the
|
|
123
|
-
* `instructions[]` membership between turns of one workspace refuses loudly
|
|
124
|
-
* (the consolidated config no longer matches byte-for-byte) rather than
|
|
125
|
-
* replacing a possibly user-authored config.
|
|
126
120
|
*/
|
|
127
|
-
export const
|
|
121
|
+
export const MATERIALIZER_RESERVED_PATHS = new Set([
|
|
128
122
|
CODEX_SYSTEM_PROMPT_FILE,
|
|
129
123
|
OPENCODE_APPEND_SYSTEM_PROMPT_FILE,
|
|
130
124
|
CONTEXT_FILE.opencode,
|
|
131
125
|
]);
|
|
126
|
+
/**
|
|
127
|
+
* The paths whose generated content is wholly this package's output, per
|
|
128
|
+
* {@link PlanFile.ownership}: the reserved names plus `opencode.json`, which
|
|
129
|
+
* carries only the registrations this package generates from the profile.
|
|
130
|
+
*
|
|
131
|
+
* `opencode.json` is a documented name a user repository can carry, so the
|
|
132
|
+
* name alone proves nothing and a profile resource may still mount it. An
|
|
133
|
+
* existing file there is replaced only when {@link isMaterializerOutput}
|
|
134
|
+
* recognizes its bytes as this package's own earlier output.
|
|
135
|
+
*
|
|
136
|
+
* Deliberately absent: `.gemini/system.md` (gemini's own documented name),
|
|
137
|
+
* `GEMINI.md`, `CLAUDE.md`, `AGENTS.md`. A user's repository can carry any of
|
|
138
|
+
* those with content this package cannot tell from its own, and clobbering
|
|
139
|
+
* one is worse than refusing the turn.
|
|
140
|
+
*/
|
|
141
|
+
export const MATERIALIZER_OWNED_PATHS = new Set([
|
|
142
|
+
...MATERIALIZER_RESERVED_PATHS,
|
|
143
|
+
OPENCODE_CONFIG_FILE,
|
|
144
|
+
]);
|
|
145
|
+
/** The top-level keys this package writes into `opencode.json`. */
|
|
146
|
+
export const OPENCODE_CONFIG_KEYS = new Set([
|
|
147
|
+
"$schema",
|
|
148
|
+
"instructions",
|
|
149
|
+
"mcp",
|
|
150
|
+
"tools",
|
|
151
|
+
"permission",
|
|
152
|
+
]);
|
|
153
|
+
/**
|
|
154
|
+
* Whether the file already at owned path `relPath` is this package's own
|
|
155
|
+
* earlier output. A reserved name proves that by itself, so `content` is read
|
|
156
|
+
* only for `opencode.json`; `undefined` content means no regular file is there.
|
|
157
|
+
*
|
|
158
|
+
* An `opencode.json` this package wrote holds the opencode schema id, only the
|
|
159
|
+
* keys this package writes, and only instruction paths this package invented.
|
|
160
|
+
* A user config that holds nothing else is indistinguishable from that output
|
|
161
|
+
* and is replaced too; a config with any other key, or with an instruction path
|
|
162
|
+
* of the user's own, is refused.
|
|
163
|
+
*/
|
|
164
|
+
export function isMaterializerOutput(relPath, content) {
|
|
165
|
+
if (MATERIALIZER_RESERVED_PATHS.has(relPath))
|
|
166
|
+
return true;
|
|
167
|
+
if (relPath !== OPENCODE_CONFIG_FILE)
|
|
168
|
+
return false;
|
|
169
|
+
const bytes = content();
|
|
170
|
+
if (bytes === undefined)
|
|
171
|
+
return false;
|
|
172
|
+
let parsed;
|
|
173
|
+
try {
|
|
174
|
+
parsed = JSON.parse(bytes);
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
const config = parsed;
|
|
183
|
+
if (config.$schema !== OPENCODE_CONFIG_SCHEMA)
|
|
184
|
+
return false;
|
|
185
|
+
if (!Object.keys(config).every((key) => OPENCODE_CONFIG_KEYS.has(key))) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
const instructions = config.instructions;
|
|
189
|
+
if (instructions === undefined)
|
|
190
|
+
return true;
|
|
191
|
+
return (Array.isArray(instructions) &&
|
|
192
|
+
instructions.every((entry) => entry === OPENCODE_APPEND_SYSTEM_PROMPT_FILE ||
|
|
193
|
+
entry === CONTEXT_FILE.opencode));
|
|
194
|
+
}
|
|
132
195
|
/**
|
|
133
196
|
* cwd-relative native skill dir per harness, or null if the harness has no
|
|
134
197
|
* cwd skill primitive (skills live in a user/global dir the workspace plan
|
package/dist/mcp.js
CHANGED
|
@@ -47,8 +47,8 @@ export function materializeMcp(h, mcp, plan, add, unsupported) {
|
|
|
47
47
|
}
|
|
48
48
|
case "opencode":
|
|
49
49
|
// opencode.json "mcp" block (local|remote).
|
|
50
|
-
add(
|
|
51
|
-
$schema:
|
|
50
|
+
add(OPENCODE_CONFIG_FILE, serializeWorkspacePlanJson({
|
|
51
|
+
$schema: OPENCODE_CONFIG_SCHEMA,
|
|
52
52
|
mcp: openCodeMcpConfig(mcp),
|
|
53
53
|
}));
|
|
54
54
|
break;
|
|
@@ -238,6 +238,7 @@ export function openCodeMcpConfig(mcp) {
|
|
|
238
238
|
}
|
|
239
239
|
return out;
|
|
240
240
|
}
|
|
241
|
+
import { OPENCODE_CONFIG_FILE, OPENCODE_CONFIG_SCHEMA } from "./harness.js";
|
|
241
242
|
import { sha256 } from "./plan-digest.js";
|
|
242
243
|
import { concatWorkspacePlanArguments, joinWorkspacePlanArguments, serializeWorkspacePlanJson, tomlProfileConfigValue, tomlStr, } from "./plan-json.js";
|
|
243
244
|
import { setPlanEnvironment } from "./profile-plan.js";
|
package/dist/plan-types.d.ts
CHANGED
|
@@ -28,16 +28,20 @@ export interface PlanFile {
|
|
|
28
28
|
* Who owns the PATH — which decides whether an existing file there may be
|
|
29
29
|
* replaced.
|
|
30
30
|
*
|
|
31
|
-
* `"materializer"` = a path
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
31
|
+
* `"materializer"` = a path whose generated content is wholly this
|
|
32
|
+
* package's output: a name this package invented, or `opencode.json`, which
|
|
33
|
+
* carries only the registrations generated from the profile. A file already
|
|
34
|
+
* there is this materializer's own output from an earlier application into
|
|
35
|
+
* the same workspace, and replacing it is how turn two of a resumed session
|
|
36
|
+
* gets the current profile instead of the previous one. Application replaces
|
|
37
|
+
* it only when the existing bytes prove that provenance — by the name for an
|
|
38
|
+
* invented path, by the content for `opencode.json`.
|
|
36
39
|
*
|
|
37
40
|
* `"shared"` (the default, and every other file) = a path the user or the
|
|
38
|
-
* harness also owns — `CLAUDE.md`, `AGENTS.md`, `
|
|
39
|
-
*
|
|
40
|
-
* file there may be the caller's own work, so it is
|
|
41
|
+
* harness also owns — `CLAUDE.md`, `AGENTS.md`, `.gemini/system.md` are all
|
|
42
|
+
* documented, user-authorable names whose content this package cannot tell
|
|
43
|
+
* from its own. An existing file there may be the caller's own work, so it is
|
|
44
|
+
* never replaced.
|
|
41
45
|
*
|
|
42
46
|
* Optional because hand-constructed plans have no path provenance to report;
|
|
43
47
|
* absent reads as `"shared"`, the safe answer.
|
package/dist/profile-plan.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MATERIALIZER_OWNED_PATHS } from "./harness.js";
|
|
1
|
+
import { MATERIALIZER_OWNED_PATHS, MATERIALIZER_RESERVED_PATHS, } from "./harness.js";
|
|
2
2
|
import { workspacePlanConfigValue } from "./plan-json.js";
|
|
3
3
|
import { mergeJsonFiles } from "./plan-normalize.js";
|
|
4
4
|
import { formatUnsupported } from "./plan-support.js";
|
|
@@ -47,7 +47,7 @@ export function createProfilePlanBuilder(harness) {
|
|
|
47
47
|
if (previousDimension) {
|
|
48
48
|
throw new Error(`Duplicate profile resource path: ${normalizedPath} (${previousDimension}, ${dimension})`);
|
|
49
49
|
}
|
|
50
|
-
if (
|
|
50
|
+
if (MATERIALIZER_RESERVED_PATHS.has(normalizedPath)) {
|
|
51
51
|
throw new Error(`Profile resource path is reserved by the materializer: ${normalizedPath} (${dimension}). ` +
|
|
52
52
|
"This package writes that path itself and replaces it on re-application, so a mount " +
|
|
53
53
|
"there cannot survive; choose another path.");
|
package/dist/profile-prompt.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { appendSystemPromptRefusal, CODEX_SYSTEM_PROMPT_FILE, CONTEXT_FILE, OPENCODE_APPEND_SYSTEM_PROMPT_FILE, OPENCODE_PRIMARY_AGENT_PREFIX, systemPromptRefusal, } from "./harness.js";
|
|
1
|
+
import { appendSystemPromptRefusal, CODEX_SYSTEM_PROMPT_FILE, CONTEXT_FILE, OPENCODE_APPEND_SYSTEM_PROMPT_FILE, OPENCODE_CONFIG_FILE, OPENCODE_CONFIG_SCHEMA, OPENCODE_PRIMARY_AGENT_PREFIX, systemPromptRefusal, } from "./harness.js";
|
|
2
2
|
import { sha256 } from "./plan-digest.js";
|
|
3
3
|
import { serializeWorkspacePlanJson } from "./plan-json.js";
|
|
4
4
|
export function lowerProfilePrompt(profile, harness, binds, builder) {
|
|
@@ -97,8 +97,8 @@ export function lowerProfilePrompt(profile, harness, binds, builder) {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
if (openCodeInstructionFiles.length > 0) {
|
|
100
|
-
add(
|
|
101
|
-
$schema:
|
|
100
|
+
add(OPENCODE_CONFIG_FILE, serializeWorkspacePlanJson({
|
|
101
|
+
$schema: OPENCODE_CONFIG_SCHEMA,
|
|
102
102
|
instructions: openCodeInstructionFiles,
|
|
103
103
|
}));
|
|
104
104
|
}
|
package/dist/workspace-apply.js
CHANGED
|
@@ -37,11 +37,14 @@ export function applyResolvedWorkspacePlan(publicPlan, resolvedPlan, workspaceDi
|
|
|
37
37
|
runtimeOnlyFiles: privateRuntimeFiles,
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
// pre-exist here", which is a statement about
|
|
44
|
-
|
|
40
|
+
// An owned path holds this package's own earlier output, so re-applying
|
|
41
|
+
// into the same workspace replaces it rather than failing the turn — once
|
|
42
|
+
// the bytes already there prove that provenance. `reject` still refuses:
|
|
43
|
+
// that policy is "nothing may pre-exist here", which is a statement about
|
|
44
|
+
// the workspace, not authorship.
|
|
45
|
+
const mayReplace = (file) => existingFiles === "allow-identical" &&
|
|
46
|
+
file.ownership === "materializer" &&
|
|
47
|
+
isMaterializerOutput(file.relPath, () => regularFileContent(file.absPath));
|
|
45
48
|
// Validate the complete plan before the first write so a late traversal or
|
|
46
49
|
// existing symlink cannot leave a partially materialized workspace.
|
|
47
50
|
for (const file of files) {
|
|
@@ -170,6 +173,11 @@ function workspaceFileExists(pathValue) {
|
|
|
170
173
|
throw error;
|
|
171
174
|
}
|
|
172
175
|
}
|
|
176
|
+
function regularFileContent(pathValue) {
|
|
177
|
+
return lstatSync(pathValue).isFile()
|
|
178
|
+
? readFileSync(pathValue, "utf8")
|
|
179
|
+
: undefined;
|
|
180
|
+
}
|
|
173
181
|
function workspaceFileMatches(file) {
|
|
174
182
|
const stats = lstatSync(file.absPath);
|
|
175
183
|
return (stats.isFile() &&
|
|
@@ -327,6 +335,7 @@ export function safeWorkspacePlanReceipt(plan, written, workspacePlanDigest = ha
|
|
|
327
335
|
import { createHash, randomUUID } from "node:crypto";
|
|
328
336
|
import { closeSync, fchmodSync, fstatSync, linkSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
329
337
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
338
|
+
import { isMaterializerOutput } from "./harness.js";
|
|
330
339
|
import { hashWorkspacePlan } from "./plan-digest.js";
|
|
331
340
|
import { normalizeWorkspacePlanArgument, } from "./plan-normalize.js";
|
|
332
341
|
import { promptIntentFields, samePromptIntentValue, systemPromptBindingField, } from "./plan-prompt.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-profile-materialize",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "Materialize an AgentProfile into the native per-harness workspace files (the one shared materializer for cli-bridge, agent-dev-container, and VB).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|