@hasna/instructions 0.4.16 → 0.4.18
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/README.md +29 -9
- package/dist/cli/index.js +229 -19
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +138 -13
- package/dist/lib/codewith-shared-todos-storage-standard.d.ts +7 -0
- package/dist/lib/codewith-shared-todos-storage-standard.d.ts.map +1 -0
- package/dist/lib/codewith-shared-todos-storage-standard.test.d.ts +2 -0
- package/dist/lib/codewith-shared-todos-storage-standard.test.d.ts.map +1 -0
- package/dist/lib/global-source-coverage.d.ts +41 -0
- package/dist/lib/global-source-coverage.d.ts.map +1 -0
- package/dist/lib/global-source-coverage.test.d.ts +2 -0
- package/dist/lib/global-source-coverage.test.d.ts.map +1 -0
- package/dist/lib/session-apply.d.ts +3 -1
- package/dist/lib/session-apply.d.ts.map +1 -1
- package/dist/lib/session-render-silent-source-drop.test.d.ts +2 -0
- package/dist/lib/session-render-silent-source-drop.test.d.ts.map +1 -0
- package/dist/lib/session-render.d.ts +11 -0
- package/dist/lib/session-render.d.ts.map +1 -1
- package/dist/mcp/index.js +49 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
# @hasna/instructions
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
share all your AI coding configs and instruction sources. CLI + MCP + HTTP API
|
|
8
|
-
(`instructions-serve`) + generated SDK + Dashboard.
|
|
3
|
+
`@hasna/instructions` stores, versions, renders, and applies configuration and
|
|
4
|
+
instruction sources for developers and platform teams operating AI coding
|
|
5
|
+
agents. Install the CLI with `bun add --global @hasna/instructions`; the package
|
|
6
|
+
also provides MCP, HTTP API, and SDK surfaces.
|
|
9
7
|
|
|
10
8
|
[](https://www.npmjs.com/package/@hasna/instructions)
|
|
11
9
|
[](LICENSE)
|
|
@@ -13,9 +11,24 @@ share all your AI coding configs and instruction sources. CLI + MCP + HTTP API
|
|
|
13
11
|
## Install
|
|
14
12
|
|
|
15
13
|
```bash
|
|
16
|
-
|
|
14
|
+
bun add --global @hasna/instructions
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
instructions --help
|
|
21
|
+
instructions init
|
|
22
|
+
instructions list
|
|
23
|
+
instructions profile resolve
|
|
17
24
|
```
|
|
18
25
|
|
|
26
|
+
## Migrating from `@hasna/configs`
|
|
27
|
+
|
|
28
|
+
This package was formerly `@hasna/configs`. The `configs` CLI alias and
|
|
29
|
+
`configs-mcp` alias remain available for existing integrations; new usage can
|
|
30
|
+
use the `instructions` names.
|
|
31
|
+
|
|
19
32
|
## CLI Usage
|
|
20
33
|
|
|
21
34
|
```bash
|
|
@@ -286,14 +299,21 @@ push safety, no brittle hardcoding when source-of-truth or reusable abstractions
|
|
|
286
299
|
exist, autonomous repair, Hasna CLI source-of-truth usage, conversation surface
|
|
287
300
|
routing, and unbudgeted Codewith goals unless a user asks for budgets.
|
|
288
301
|
|
|
289
|
-
They also seed `dangerous-operation-guard-standard`, the managed
|
|
290
|
-
|
|
302
|
+
They also seed `dangerous-operation-guard-standard`, the managed guard source
|
|
303
|
+
for risky shell commands, edits, git operations, package installs, and
|
|
291
304
|
secret-adjacent access. The guard excludes Gemini CLI, requires Codewith/Codex
|
|
292
305
|
`PreToolUse` to hard-deny or inject context rather than ask for approval, uses
|
|
293
306
|
`PermissionRequest` for Codewith/Codex approvals, records that Qwen `QWEN.md`
|
|
294
307
|
is policy context only, and records native hook or wrapper/plugin fallback
|
|
295
308
|
expectations for Claude, Qwen, OpenCode, Cursor, and Antigravity.
|
|
296
309
|
|
|
310
|
+
The Codewith-only `codewith-shared-todos-storage-standard` requires every
|
|
311
|
+
operational repository, work or research project, coordinator, worker, and loop
|
|
312
|
+
to use the managed shared Todos route. On-box SQLite or file Todos storage is limited
|
|
313
|
+
to disposable repository tests. Projects linkage and sanitized server-route
|
|
314
|
+
verification are required before mutation; unavailable routing fails closed,
|
|
315
|
+
and prior on-box-only evidence must be explicitly reconciled before use.
|
|
316
|
+
|
|
297
317
|
## Machine-aware Profiles
|
|
298
318
|
|
|
299
319
|
`instructions init` seeds two platform profiles:
|
package/dist/cli/index.js
CHANGED
|
@@ -3412,6 +3412,86 @@ var init_global_agent_rules_standard = __esm(() => {
|
|
|
3412
3412
|
`;
|
|
3413
3413
|
});
|
|
3414
3414
|
|
|
3415
|
+
// src/lib/codewith-shared-todos-storage-standard.ts
|
|
3416
|
+
async function ensureCodewithSharedTodosStorageStandardConfig(store = resolveConfigStore()) {
|
|
3417
|
+
const input = {
|
|
3418
|
+
name: "Codewith Shared Todos Storage Standard",
|
|
3419
|
+
category: "rules",
|
|
3420
|
+
agent: "codewith",
|
|
3421
|
+
format: "markdown",
|
|
3422
|
+
content: CODEWITH_SHARED_TODOS_STORAGE_STANDARD_CONTENT,
|
|
3423
|
+
kind: "reference",
|
|
3424
|
+
description: "Managed fail-closed shared Todos routing policy for all operational Codewith work",
|
|
3425
|
+
tags: [
|
|
3426
|
+
"codewith",
|
|
3427
|
+
"shared-todos-storage",
|
|
3428
|
+
"server-backed",
|
|
3429
|
+
"projects-linkage",
|
|
3430
|
+
"operational-routing"
|
|
3431
|
+
]
|
|
3432
|
+
};
|
|
3433
|
+
let config;
|
|
3434
|
+
try {
|
|
3435
|
+
const existing = await store.getConfig(CODEWITH_SHARED_TODOS_STORAGE_STANDARD_SLUG);
|
|
3436
|
+
if (existing.content !== input.content || existing.description !== input.description || existing.category !== input.category || existing.agent !== input.agent || existing.format !== input.format || existing.kind !== input.kind || JSON.stringify(existing.tags) !== JSON.stringify(input.tags)) {
|
|
3437
|
+
config = await store.updateConfig(existing.id, input);
|
|
3438
|
+
} else {
|
|
3439
|
+
config = existing;
|
|
3440
|
+
}
|
|
3441
|
+
} catch {
|
|
3442
|
+
config = await store.createConfig(input);
|
|
3443
|
+
}
|
|
3444
|
+
for (const profile of await store.listProfiles()) {
|
|
3445
|
+
await store.addConfigToProfile(profile.id, config.id);
|
|
3446
|
+
}
|
|
3447
|
+
return config;
|
|
3448
|
+
}
|
|
3449
|
+
var CODEWITH_SHARED_TODOS_STORAGE_STANDARD_SLUG = "codewith-shared-todos-storage-standard", CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE = "codewith/shared-todos-storage/v1", CODEWITH_SHARED_TODOS_STORAGE_STANDARD_CONTENT;
|
|
3450
|
+
var init_codewith_shared_todos_storage_standard = __esm(() => {
|
|
3451
|
+
init_config_store();
|
|
3452
|
+
CODEWITH_SHARED_TODOS_STORAGE_STANDARD_CONTENT = `# Codewith Shared Todos Storage Standard
|
|
3453
|
+
|
|
3454
|
+
Policy reference: \`${CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE}\`
|
|
3455
|
+
|
|
3456
|
+
## Scope
|
|
3457
|
+
|
|
3458
|
+
- This policy applies to all operational Codewith work: repositories of every
|
|
3459
|
+
name, work projects, research projects, coordinators, delegated workers, and
|
|
3460
|
+
native scheduled or recurring loops. It is not limited to \`open-*\` or
|
|
3461
|
+
\`iapp-*\` repositories.
|
|
3462
|
+
|
|
3463
|
+
## Authoritative Storage
|
|
3464
|
+
|
|
3465
|
+
- Operational Todos state must use the managed shared Todos service.
|
|
3466
|
+
On-box SQLite or file storage is permitted only inside disposable,
|
|
3467
|
+
repository-owned tests using isolated test-controlled paths.
|
|
3468
|
+
- On-box SQLite or file storage must never hold operational tasks, plans, locks or claims,
|
|
3469
|
+
comments, verification evidence, dispatch state, or handoff state. Never
|
|
3470
|
+
fall back to on-box-only storage to keep operational work moving.
|
|
3471
|
+
|
|
3472
|
+
## Pre-Mutation Gate
|
|
3473
|
+
|
|
3474
|
+
- Before any operational Todos mutation, require authoritative Projects
|
|
3475
|
+
linkage and verify from sanitized status or route metadata that Todos resolves
|
|
3476
|
+
to the managed server-backed route. Verification may identify the route class,
|
|
3477
|
+
backend class, and linked project identifiers, but must omit credentials,
|
|
3478
|
+
tokens, DSNs, and full endpoint URLs.
|
|
3479
|
+
- If Projects linkage or server-backed route verification is missing, ambiguous,
|
|
3480
|
+
unavailable, or reports an on-box SQLite or file route, fail closed: do not mutate Todos.
|
|
3481
|
+
Diagnose and repair the owning configuration or service route, re-run the
|
|
3482
|
+
sanitized verification, and report the blockage or repair on the approved
|
|
3483
|
+
operational surface without exposing secrets.
|
|
3484
|
+
|
|
3485
|
+
## Reconciliation
|
|
3486
|
+
|
|
3487
|
+
- Prior on-box-only tasks, plans, comments, locks, verification, dispatch, or
|
|
3488
|
+
handoff evidence are not authoritative. Explicitly reconcile each required
|
|
3489
|
+
record into the Projects-linked shared Todos record, retain bounded provenance
|
|
3490
|
+
identifiers, and independently verify the shared result before treating it as
|
|
3491
|
+
authoritative. Never silently copy, discard, or bless on-box-only evidence.
|
|
3492
|
+
`;
|
|
3493
|
+
});
|
|
3494
|
+
|
|
3415
3495
|
// node_modules/zod/v3/helpers/util.js
|
|
3416
3496
|
var util, objectUtil, ZodParsedType, getParsedType = (data) => {
|
|
3417
3497
|
const t = typeof data;
|
|
@@ -10389,6 +10469,14 @@ function applyAgentOperatingRulesFloor(source, content) {
|
|
|
10389
10469
|
metadata: { ...source.metadata ?? {}, ...payload.metadata, ...floored }
|
|
10390
10470
|
};
|
|
10391
10471
|
}
|
|
10472
|
+
function skippedSource(source, reason) {
|
|
10473
|
+
return {
|
|
10474
|
+
id: source.id,
|
|
10475
|
+
label: source.resolvedLabel,
|
|
10476
|
+
targetProviders: source.targetProviders ?? [],
|
|
10477
|
+
reason
|
|
10478
|
+
};
|
|
10479
|
+
}
|
|
10392
10480
|
function normalizeSources(sources, tool, allowEmptySources) {
|
|
10393
10481
|
const normalized = sources.map((source, index) => {
|
|
10394
10482
|
if (!source.id.trim())
|
|
@@ -10413,14 +10501,17 @@ function normalizeSources(sources, tool, allowEmptySources) {
|
|
|
10413
10501
|
}
|
|
10414
10502
|
return normalized2;
|
|
10415
10503
|
});
|
|
10416
|
-
const
|
|
10504
|
+
const deduplicated = deduplicateSemanticPolicySources(normalized);
|
|
10505
|
+
const ordered = deduplicated.selected.sort((a, b) => SESSION_LAYER_RANK[a.resolvedLayer] - SESSION_LAYER_RANK[b.resolvedLayer] || a.resolvedOrder - b.resolvedOrder || a.id.localeCompare(b.id));
|
|
10417
10506
|
rejectDuplicateSourceSlugs(ordered);
|
|
10418
10507
|
rejectDuplicateRulePaths(ordered);
|
|
10419
|
-
return ordered;
|
|
10508
|
+
return { sources: ordered, skipped: deduplicated.skipped };
|
|
10420
10509
|
}
|
|
10421
10510
|
function deduplicateSemanticPolicySources(sources) {
|
|
10422
10511
|
const selected = [];
|
|
10512
|
+
const skipped = [];
|
|
10423
10513
|
const policySources = new Map;
|
|
10514
|
+
const collapseReason = (winner, key) => `superseded by "${winner.id}": sources declaring the semantic policy ${key} collapse to one so a single instruction home cannot carry two rule-set versions`;
|
|
10424
10515
|
for (const source of sources) {
|
|
10425
10516
|
const sentinel = source.content.match(AGENT_OPERATING_RULES_SENTINEL_PATTERN);
|
|
10426
10517
|
if (!sentinel) {
|
|
@@ -10443,17 +10534,18 @@ function deduplicateSemanticPolicySources(sources) {
|
|
|
10443
10534
|
}
|
|
10444
10535
|
const current = selected[existing.index];
|
|
10445
10536
|
const priorityOrder = semanticPolicySourcePriority(source) - semanticPolicySourcePriority(current);
|
|
10446
|
-
if (priorityOrder < 0)
|
|
10447
|
-
|
|
10448
|
-
if (priorityOrder === 0 && versionOrder <= 0)
|
|
10537
|
+
if (priorityOrder < 0 || priorityOrder === 0 && versionOrder <= 0) {
|
|
10538
|
+
skipped.push(skippedSource(source, collapseReason(current, key)));
|
|
10449
10539
|
continue;
|
|
10540
|
+
}
|
|
10541
|
+
skipped.push(skippedSource(current, collapseReason(source, key)));
|
|
10450
10542
|
selected[existing.index] = {
|
|
10451
10543
|
...source,
|
|
10452
10544
|
resolvedOrder: current.resolvedOrder
|
|
10453
10545
|
};
|
|
10454
10546
|
policySources.set(key, { index: existing.index, version, normalizedContent });
|
|
10455
10547
|
}
|
|
10456
|
-
return selected;
|
|
10548
|
+
return { selected, skipped };
|
|
10457
10549
|
}
|
|
10458
10550
|
function semanticPolicySourcePriority(source) {
|
|
10459
10551
|
let priority = 0;
|
|
@@ -10499,9 +10591,12 @@ function composeSources(sources) {
|
|
|
10499
10591
|
start = i;
|
|
10500
10592
|
}
|
|
10501
10593
|
if (start < 0)
|
|
10502
|
-
return sources;
|
|
10503
|
-
const
|
|
10504
|
-
|
|
10594
|
+
return { sources, skipped: [] };
|
|
10595
|
+
const earlier = sources.slice(0, start);
|
|
10596
|
+
const protectedSources = earlier.filter((source) => source.nonOverridable);
|
|
10597
|
+
const replacer = sources[start];
|
|
10598
|
+
const skipped = earlier.filter((source) => !source.nonOverridable).map((source) => skippedSource(source, `superseded by "${replacer.id}": a replace-merge source discards earlier overridable instruction layers`));
|
|
10599
|
+
return { sources: [...protectedSources, ...sources.slice(start)], skipped };
|
|
10505
10600
|
}
|
|
10506
10601
|
function sectionForSource(source) {
|
|
10507
10602
|
const parts = [
|
|
@@ -10876,7 +10971,14 @@ function planSessionRender(input) {
|
|
|
10876
10971
|
const targetOwner = resolveSessionTargetOwnership(input, { targetHome, targetKind });
|
|
10877
10972
|
const blocked = blockers.length > 0;
|
|
10878
10973
|
const allowEmptySources = input.allowEmptySources === true;
|
|
10879
|
-
const
|
|
10974
|
+
const normalized = normalizeSources(input.sources, input.tool, allowEmptySources);
|
|
10975
|
+
const composed = composeSources(normalized.sources);
|
|
10976
|
+
const orderedSources = composed.sources;
|
|
10977
|
+
const skippedSources = [
|
|
10978
|
+
...input.skippedSources ?? [],
|
|
10979
|
+
...normalized.skipped,
|
|
10980
|
+
...composed.skipped
|
|
10981
|
+
];
|
|
10880
10982
|
if (orderedSources.length === 0 && !allowEmptySources) {
|
|
10881
10983
|
throw new Error("Session render has no instruction sources. Pass --allow-empty-sources only for explicit empty renders.");
|
|
10882
10984
|
}
|
|
@@ -10884,7 +10986,8 @@ function planSessionRender(input) {
|
|
|
10884
10986
|
const env = adapter.envVar && !blocked ? { [adapter.envVar]: targetHome } : {};
|
|
10885
10987
|
const warnings = [
|
|
10886
10988
|
...orderedSources.length === 0 ? ["No instruction sources were provided."] : [],
|
|
10887
|
-
...blockers
|
|
10989
|
+
...blockers,
|
|
10990
|
+
...skippedSources.map((entry) => `Instruction source "${entry.id}" was not rendered: ${entry.reason}`)
|
|
10888
10991
|
];
|
|
10889
10992
|
if (input.providerConfig && input.tool !== "opencode") {
|
|
10890
10993
|
throw new Error("Provider base config is supported only for OpenCode session renders.");
|
|
@@ -10956,7 +11059,7 @@ function planSessionRender(input) {
|
|
|
10956
11059
|
})),
|
|
10957
11060
|
...projectContext ? [projectContext.source] : []
|
|
10958
11061
|
],
|
|
10959
|
-
skippedSources
|
|
11062
|
+
skippedSources,
|
|
10960
11063
|
files: files.map((file) => ({
|
|
10961
11064
|
path: file.path,
|
|
10962
11065
|
relativePath: file.relativePath,
|
|
@@ -10991,6 +11094,7 @@ function planSessionRender(input) {
|
|
|
10991
11094
|
writable: !blocked,
|
|
10992
11095
|
blocked,
|
|
10993
11096
|
blockers,
|
|
11097
|
+
allowEmptySources,
|
|
10994
11098
|
env,
|
|
10995
11099
|
files,
|
|
10996
11100
|
manifest,
|
|
@@ -11013,6 +11117,7 @@ function sourceFromFilePath(path, content, order = 0) {
|
|
|
11013
11117
|
}
|
|
11014
11118
|
function sourceFromConfig(config, order = 0, layer) {
|
|
11015
11119
|
const isAgentOperatingRules = config.slug === GLOBAL_AGENT_RULES_STANDARD_SLUG;
|
|
11120
|
+
const isNonOverridableManagedPolicy = isAgentOperatingRules || config.slug === CODEWITH_SHARED_TODOS_STORAGE_STANDARD_SLUG;
|
|
11016
11121
|
const rules = isAgentOperatingRules ? resolveAgentOperatingRulesPayload(config.content) : null;
|
|
11017
11122
|
return {
|
|
11018
11123
|
id: config.slug,
|
|
@@ -11031,7 +11136,7 @@ function sourceFromConfig(config, order = 0, layer) {
|
|
|
11031
11136
|
configAgent: config.agent
|
|
11032
11137
|
},
|
|
11033
11138
|
metadata: rules ? { ...rules.metadata } : null,
|
|
11034
|
-
nonOverridable:
|
|
11139
|
+
nonOverridable: isNonOverridableManagedPolicy
|
|
11035
11140
|
};
|
|
11036
11141
|
}
|
|
11037
11142
|
function sourcesFromIdentityExport(value, options = {}) {
|
|
@@ -11321,6 +11426,7 @@ function asStringArray(value) {
|
|
|
11321
11426
|
var RAW_STORE_ROOT_ENV = "HASNA_CONFIGS_HOME", ANTIGRAVITY_RULE_FILE_CHAR_LIMIT = 12000, SESSION_RENDERER_OWNER_ID = "instructions-session-renderer", SESSION_RENDER_TOOLS, SESSION_RENDER_PROFILE_ENTRYPOINTS, SESSION_RENDER_OWNED_CONFIG_TARGETS, CODEWITH_FLATTENED_ADAPTER, CODEWITH_NATIVE_ADAPTER, SESSION_TOOL_ADAPTERS, SESSION_RENDER_MANAGED_DIRS, SESSION_RENDER_SHARED_MANAGED_DIRS, SESSION_RENDER_EXCLUSIVE_MANAGED_PATHS, SESSION_LAYER_RANK, CANONICAL_IDENTITY_EXPORT_PACKAGES;
|
|
11322
11427
|
var init_session_render = __esm(() => {
|
|
11323
11428
|
init_global_agent_rules_standard();
|
|
11429
|
+
init_codewith_shared_todos_storage_standard();
|
|
11324
11430
|
init_project_context();
|
|
11325
11431
|
init_config_agents();
|
|
11326
11432
|
init_transforms();
|
|
@@ -13865,6 +13971,7 @@ function applySessionRenderUnlocked(plan, options, coordination) {
|
|
|
13865
13971
|
...files.map((file) => planFileResult(plan, file, targetHome, previousHashes, previousManifest, options)),
|
|
13866
13972
|
...planStaleFileResults(plan, targetHome, previousManifest, currentRelativePaths, options)
|
|
13867
13973
|
];
|
|
13974
|
+
assertNotSilentManagedWipeout(plan, results);
|
|
13868
13975
|
const conflicts = results.filter((result) => result.action === "conflict");
|
|
13869
13976
|
if (conflicts.length > 0) {
|
|
13870
13977
|
return {
|
|
@@ -13874,6 +13981,8 @@ function applySessionRenderUnlocked(plan, options, coordination) {
|
|
|
13874
13981
|
manifestPath,
|
|
13875
13982
|
snapshotPath: null,
|
|
13876
13983
|
env: plan.env,
|
|
13984
|
+
warnings: plan.warnings,
|
|
13985
|
+
skippedSources: plan.manifest.skippedSources,
|
|
13877
13986
|
files: results,
|
|
13878
13987
|
conflicts,
|
|
13879
13988
|
drift
|
|
@@ -13914,6 +14023,8 @@ function applySessionRenderUnlocked(plan, options, coordination) {
|
|
|
13914
14023
|
manifestPath,
|
|
13915
14024
|
snapshotPath,
|
|
13916
14025
|
env: plan.env,
|
|
14026
|
+
warnings: plan.warnings,
|
|
14027
|
+
skippedSources: plan.manifest.skippedSources,
|
|
13917
14028
|
files: results,
|
|
13918
14029
|
conflicts,
|
|
13919
14030
|
drift
|
|
@@ -14437,6 +14548,19 @@ function planFileResult(plan, file, targetHome, previousHashes, previousManifest
|
|
|
14437
14548
|
reason: "existing unmanaged file differs; pass force to overwrite"
|
|
14438
14549
|
};
|
|
14439
14550
|
}
|
|
14551
|
+
function assertNotSilentManagedWipeout(plan, results) {
|
|
14552
|
+
if (plan.allowEmptySources)
|
|
14553
|
+
return;
|
|
14554
|
+
const managedDir = plan.adapter.managedDir;
|
|
14555
|
+
const underManagedDir = (relativePath) => relativePath === managedDir || relativePath.startsWith(`${managedDir}/`);
|
|
14556
|
+
const staleDeletions = results.filter((result) => result.action === "delete" && underManagedDir(result.relativePath));
|
|
14557
|
+
if (staleDeletions.length === 0)
|
|
14558
|
+
return;
|
|
14559
|
+
const managedRetained = results.some((result) => result.action !== "delete" && underManagedDir(result.relativePath));
|
|
14560
|
+
if (managedRetained)
|
|
14561
|
+
return;
|
|
14562
|
+
throw new SessionApplyError(`Session render plan for ${plan.tool} (${plan.adapter.mode}) would delete ${staleDeletions.length} ` + `previously managed file(s) under "${managedDir}" and create or update none there: ` + `${staleDeletions.map((result) => result.relativePath).join(", ")}. ` + "Pass --allow-empty-sources only for explicit empty renders.");
|
|
14563
|
+
}
|
|
14440
14564
|
function planStaleFileResults(plan, targetHome, previousManifest, currentRelativePaths, options) {
|
|
14441
14565
|
if (!previousManifest)
|
|
14442
14566
|
return [];
|
|
@@ -14668,6 +14792,37 @@ function sha2564(content) {
|
|
|
14668
14792
|
// src/cli/index.tsx
|
|
14669
14793
|
init_session_render();
|
|
14670
14794
|
|
|
14795
|
+
// src/lib/global-source-coverage.ts
|
|
14796
|
+
var GLOBAL_SOURCE_SLUG_PREFIX = "global-";
|
|
14797
|
+
var RETIRED_GLOBAL_SOURCE_TAG = "retired-global-source";
|
|
14798
|
+
function expectedGlobalSourceSlugs(registryConfigs) {
|
|
14799
|
+
return registryConfigs.filter((c) => c.slug.startsWith(GLOBAL_SOURCE_SLUG_PREFIX)).filter((c) => !(c.tags ?? []).includes(RETIRED_GLOBAL_SOURCE_TAG)).map((c) => c.slug).sort();
|
|
14800
|
+
}
|
|
14801
|
+
function accountedGlobalSourceSlugs(manifest) {
|
|
14802
|
+
return [...manifest.sources, ...manifest.skippedSources].map((source) => source.id).filter((id) => id.startsWith(GLOBAL_SOURCE_SLUG_PREFIX));
|
|
14803
|
+
}
|
|
14804
|
+
function computeGlobalSourceCoverage(registryConfigs, configuredSlugs) {
|
|
14805
|
+
const expected = expectedGlobalSourceSlugs(registryConfigs);
|
|
14806
|
+
const expectedSet = new Set(expected);
|
|
14807
|
+
const configuredSet = new Set(configuredSlugs);
|
|
14808
|
+
const missing = expected.filter((slug2) => !configuredSet.has(slug2));
|
|
14809
|
+
const unexpected = [...configuredSet].filter((slug2) => slug2.startsWith(GLOBAL_SOURCE_SLUG_PREFIX) && !expectedSet.has(slug2)).sort();
|
|
14810
|
+
return {
|
|
14811
|
+
expectedSlugs: expected,
|
|
14812
|
+
configuredSlugs: [...configuredSet].sort(),
|
|
14813
|
+
missingSlugs: missing,
|
|
14814
|
+
unexpectedSlugs: unexpected,
|
|
14815
|
+
complete: missing.length === 0
|
|
14816
|
+
};
|
|
14817
|
+
}
|
|
14818
|
+
function formatGlobalSourceCoverageWarnings(result) {
|
|
14819
|
+
if (result.complete)
|
|
14820
|
+
return [];
|
|
14821
|
+
return [
|
|
14822
|
+
`Global source coverage: ${result.expectedSlugs.length - result.missingSlugs.length}/${result.expectedSlugs.length} registered global-* sources are in this render. Missing: ${result.missingSlugs.join(", ")}`
|
|
14823
|
+
];
|
|
14824
|
+
}
|
|
14825
|
+
|
|
14671
14826
|
// src/lib/platform-profiles.ts
|
|
14672
14827
|
init_config_store();
|
|
14673
14828
|
|
|
@@ -14974,6 +15129,7 @@ async function ensureDangerousOperationGuardStandardConfig(store = resolveConfig
|
|
|
14974
15129
|
}
|
|
14975
15130
|
|
|
14976
15131
|
// src/cli/index.tsx
|
|
15132
|
+
init_codewith_shared_todos_storage_standard();
|
|
14977
15133
|
init_project_context();
|
|
14978
15134
|
|
|
14979
15135
|
// src/status.ts
|
|
@@ -15333,6 +15489,11 @@ async function collectSessionSources(opts, tool, store) {
|
|
|
15333
15489
|
}
|
|
15334
15490
|
return sources.map((source) => replaceIds.has(source.id) ? { ...source, merge: "replace" } : source);
|
|
15335
15491
|
}
|
|
15492
|
+
async function checkGlobalSourceCoverage(plan, store) {
|
|
15493
|
+
const registryConfigs = await store.listConfigs({});
|
|
15494
|
+
const configuredSlugs = accountedGlobalSourceSlugs(plan.manifest);
|
|
15495
|
+
return computeGlobalSourceCoverage(registryConfigs, configuredSlugs);
|
|
15496
|
+
}
|
|
15336
15497
|
function stripSessionFileContent(file) {
|
|
15337
15498
|
const { content: _content, ...rest } = file;
|
|
15338
15499
|
return rest;
|
|
@@ -15496,6 +15657,28 @@ program.command("show <id>").alias("inspect").description("Show a config's conte
|
|
|
15496
15657
|
process.exit(1);
|
|
15497
15658
|
}
|
|
15498
15659
|
});
|
|
15660
|
+
program.command("tag <id>").description("Add or remove tags on a stored config (metadata-only; content/target_path untouched)").option("--add <tag>", "tag to add; repeatable", collectOption, []).option("--remove <tag>", "tag to remove; repeatable", collectOption, []).option("--json", "output the updated config as JSON").action(async (id, opts) => {
|
|
15661
|
+
const add = opts.add;
|
|
15662
|
+
const remove = opts.remove;
|
|
15663
|
+
if (add.length === 0 && remove.length === 0) {
|
|
15664
|
+
console.error(chalk.red("Pass at least one --add <tag> or --remove <tag>."));
|
|
15665
|
+
process.exit(1);
|
|
15666
|
+
}
|
|
15667
|
+
const store = resolveConfigStore();
|
|
15668
|
+
const config = await store.getConfig(id);
|
|
15669
|
+
const tagSet = new Set(config.tags);
|
|
15670
|
+
for (const t of add)
|
|
15671
|
+
tagSet.add(t);
|
|
15672
|
+
for (const t of remove)
|
|
15673
|
+
tagSet.delete(t);
|
|
15674
|
+
const nextTags = [...tagSet].sort();
|
|
15675
|
+
const updated = await store.updateConfig(config.id, { tags: nextTags });
|
|
15676
|
+
if (opts.json) {
|
|
15677
|
+
printJson(updated);
|
|
15678
|
+
return;
|
|
15679
|
+
}
|
|
15680
|
+
console.log(chalk.green("\u2713") + ` Tags on ${chalk.bold(updated.name)} ${chalk.dim(`(${updated.slug})`)}: ${nextTags.join(", ") || chalk.dim("(none)")}`);
|
|
15681
|
+
});
|
|
15499
15682
|
program.command("add <path>").description("Ingest a file into the config DB").option("-n, --name <name>", "config name (defaults to filename)").option("-c, --category <cat>", "category override").option("-a, --agent <agent>", "agent override").option("-k, --kind <kind>", "kind: file|reference", "file").option("--template", "mark as template (has {{VAR}} placeholders)").option("--update", "if a config already owns this path, update that row in place instead of refusing").action(async (filePath, opts) => {
|
|
15500
15683
|
const abs = resolve8(filePath);
|
|
15501
15684
|
if (!existsSync16(abs)) {
|
|
@@ -15991,14 +16174,15 @@ projectContextCmd.command("apply").description("Atomically write project context
|
|
|
15991
16174
|
}
|
|
15992
16175
|
});
|
|
15993
16176
|
var sessionCmd = program.command("session").description("Plan and apply session-scoped agent instruction files");
|
|
15994
|
-
sessionCmd.command("plan").description("Produce a dry-run render plan for profile-scoped instruction injection").requiredOption("--tool <tool>", `target tool (${SESSION_RENDER_TOOLS.join("|")})`).requiredOption("--profile <profile>", "account/profile name that owns the rendered instruction home").option("--target-home <path>", "override generated profile-scoped target home").option("--project-root <path>", "repository root for project-scoped adapters such as Cursor").option("--session-id <id>", "session id to include in the manifest").option("--source <layer:id=path>", `instruction source file; layers: ${SESSION_SOURCE_LAYER_HELP}`, collectOption, []).option("--config <layer:id-or-slug>", "stored config source by id/slug; repeatable; layer aliases match --source", collectOption, []).option("--identity-export <path>", "OpenIdentities configs instruction export JSON; repeatable", collectOption, []).option("--replace-source <id>", "source id that replaces earlier layers instead of appending", collectOption, []).option("--codewith-native-imports", "select the gated Codewith native @ import adapter").option("--allow-empty-sources", "allow an explicit empty render plan").option("--json", "output dry-run JSON").action(async (opts) => {
|
|
16177
|
+
sessionCmd.command("plan").description("Produce a dry-run render plan for profile-scoped instruction injection").requiredOption("--tool <tool>", `target tool (${SESSION_RENDER_TOOLS.join("|")})`).requiredOption("--profile <profile>", "account/profile name that owns the rendered instruction home").option("--target-home <path>", "override generated profile-scoped target home").option("--project-root <path>", "repository root for project-scoped adapters such as Cursor").option("--session-id <id>", "session id to include in the manifest").option("--source <layer:id=path>", `instruction source file; layers: ${SESSION_SOURCE_LAYER_HELP}`, collectOption, []).option("--config <layer:id-or-slug>", "stored config source by id/slug; repeatable; layer aliases match --source", collectOption, []).option("--identity-export <path>", "OpenIdentities configs instruction export JSON; repeatable", collectOption, []).option("--replace-source <id>", "source id that replaces earlier layers instead of appending", collectOption, []).option("--codewith-native-imports", "select the gated Codewith native @ import adapter").option("--allow-empty-sources", "allow an explicit empty render plan").option("--check-global-coverage", "warn (non-fatal) when a registered, non-retired global-* source is absent from this render's --config list; expected is read fresh from the registry, independent of this plan (todos 102d6d0a)").option("--json", "output dry-run JSON").action(async (opts) => {
|
|
15995
16178
|
try {
|
|
15996
16179
|
const tool = opts.tool;
|
|
15997
16180
|
if (!SESSION_RENDER_TOOLS.includes(tool)) {
|
|
15998
16181
|
console.error(chalk.red(`Unsupported tool: ${opts.tool}`));
|
|
15999
16182
|
process.exit(1);
|
|
16000
16183
|
}
|
|
16001
|
-
const
|
|
16184
|
+
const store = resolveConfigStore();
|
|
16185
|
+
const sources = await collectSessionSources(opts, tool, store);
|
|
16002
16186
|
const plan = planSessionRender({
|
|
16003
16187
|
tool,
|
|
16004
16188
|
profile: opts.profile,
|
|
@@ -16009,8 +16193,12 @@ sessionCmd.command("plan").description("Produce a dry-run render plan for profil
|
|
|
16009
16193
|
allowEmptySources: opts.allowEmptySources,
|
|
16010
16194
|
sources
|
|
16011
16195
|
});
|
|
16196
|
+
const globalCoverage = opts.checkGlobalCoverage ? await checkGlobalSourceCoverage(plan, store) : null;
|
|
16012
16197
|
if (opts.json) {
|
|
16013
|
-
printJson(
|
|
16198
|
+
printJson({
|
|
16199
|
+
...planJsonForOutput(plan),
|
|
16200
|
+
...globalCoverage ? { globalSourceCoverage: globalCoverage } : {}
|
|
16201
|
+
});
|
|
16014
16202
|
return;
|
|
16015
16203
|
}
|
|
16016
16204
|
console.log(chalk.bold(`${plan.tool} session render plan`) + chalk.dim(` (${plan.adapter.mode})`));
|
|
@@ -16030,20 +16218,27 @@ sessionCmd.command("plan").description("Produce a dry-run render plan for profil
|
|
|
16030
16218
|
for (const warning of plan.warnings)
|
|
16031
16219
|
console.log(chalk.yellow(`warning: ${warning}`));
|
|
16032
16220
|
}
|
|
16221
|
+
if (globalCoverage) {
|
|
16222
|
+
for (const warning of formatGlobalSourceCoverageWarnings(globalCoverage))
|
|
16223
|
+
console.log(chalk.yellow(`warning: ${warning}`));
|
|
16224
|
+
if (globalCoverage.complete)
|
|
16225
|
+
console.log(chalk.dim(`global source coverage: ${globalCoverage.expectedSlugs.length}/${globalCoverage.expectedSlugs.length} complete`));
|
|
16226
|
+
}
|
|
16033
16227
|
console.log(chalk.dim("Dry run only. No files were written."));
|
|
16034
16228
|
} catch (e) {
|
|
16035
16229
|
console.error(chalk.red(formatCliError(e)));
|
|
16036
16230
|
process.exit(1);
|
|
16037
16231
|
}
|
|
16038
16232
|
});
|
|
16039
|
-
sessionCmd.command("apply").description("Write a session render plan to its managed target home or explicit project root").requiredOption("--tool <tool>", `target tool (${SESSION_RENDER_TOOLS.join("|")})`).requiredOption("--profile <profile>", "account/profile name that owns the rendered instruction home").option("--target-home <path>", "override generated profile-scoped target home").option("--project-root <path>", "repository root for project-scoped adapters such as Cursor").option("--session-id <id>", "session id to include in the manifest").option("--source <layer:id=path>", `instruction source file; layers: ${SESSION_SOURCE_LAYER_HELP}`, collectOption, []).option("--config <layer:id-or-slug>", "stored config source by id/slug; repeatable; layer aliases match --source", collectOption, []).option("--identity-export <path>", "OpenIdentities configs instruction export JSON; repeatable", collectOption, []).option("--replace-source <id>", "source id that replaces earlier layers instead of appending", collectOption, []).option("--codewith-native-imports", "select the gated Codewith native @ import adapter").option("--allow-empty-sources", "allow an explicit empty render").option("--dry-run", "preview writes and conflicts without writing").option("--force", "overwrite existing unmanaged files").option("--json", "output apply JSON").action(async (opts) => {
|
|
16233
|
+
sessionCmd.command("apply").description("Write a session render plan to its managed target home or explicit project root").requiredOption("--tool <tool>", `target tool (${SESSION_RENDER_TOOLS.join("|")})`).requiredOption("--profile <profile>", "account/profile name that owns the rendered instruction home").option("--target-home <path>", "override generated profile-scoped target home").option("--project-root <path>", "repository root for project-scoped adapters such as Cursor").option("--session-id <id>", "session id to include in the manifest").option("--source <layer:id=path>", `instruction source file; layers: ${SESSION_SOURCE_LAYER_HELP}`, collectOption, []).option("--config <layer:id-or-slug>", "stored config source by id/slug; repeatable; layer aliases match --source", collectOption, []).option("--identity-export <path>", "OpenIdentities configs instruction export JSON; repeatable", collectOption, []).option("--replace-source <id>", "source id that replaces earlier layers instead of appending", collectOption, []).option("--codewith-native-imports", "select the gated Codewith native @ import adapter").option("--allow-empty-sources", "allow an explicit empty render").option("--check-global-coverage", "warn (non-fatal) when a registered, non-retired global-* source is absent from this render's --config list; expected is read fresh from the registry, independent of this plan (todos 102d6d0a)").option("--dry-run", "preview writes and conflicts without writing").option("--force", "overwrite existing unmanaged files").option("--json", "output apply JSON").action(async (opts) => {
|
|
16040
16234
|
try {
|
|
16041
16235
|
const tool = opts.tool;
|
|
16042
16236
|
if (!SESSION_RENDER_TOOLS.includes(tool)) {
|
|
16043
16237
|
console.error(chalk.red(`Unsupported tool: ${opts.tool}`));
|
|
16044
16238
|
process.exit(1);
|
|
16045
16239
|
}
|
|
16046
|
-
const
|
|
16240
|
+
const store = resolveConfigStore();
|
|
16241
|
+
const sources = await collectSessionSources(opts, tool, store);
|
|
16047
16242
|
const plan = planSessionRender({
|
|
16048
16243
|
tool,
|
|
16049
16244
|
profile: opts.profile,
|
|
@@ -16054,9 +16249,13 @@ sessionCmd.command("apply").description("Write a session render plan to its mana
|
|
|
16054
16249
|
allowEmptySources: opts.allowEmptySources,
|
|
16055
16250
|
sources
|
|
16056
16251
|
});
|
|
16252
|
+
const globalCoverage = opts.checkGlobalCoverage ? await checkGlobalSourceCoverage(plan, store) : null;
|
|
16057
16253
|
const result = applySessionRender(plan, { dryRun: opts.dryRun, force: opts.force });
|
|
16058
16254
|
if (opts.json) {
|
|
16059
|
-
printJson(
|
|
16255
|
+
printJson({
|
|
16256
|
+
...result,
|
|
16257
|
+
...globalCoverage ? { globalSourceCoverage: globalCoverage } : {}
|
|
16258
|
+
});
|
|
16060
16259
|
if (result.conflicts.length > 0)
|
|
16061
16260
|
process.exitCode = 1;
|
|
16062
16261
|
return;
|
|
@@ -16079,6 +16278,16 @@ sessionCmd.command("apply").description("Write a session render plan to its mana
|
|
|
16079
16278
|
if (file.reason)
|
|
16080
16279
|
console.log(chalk.dim(` ${file.reason}`));
|
|
16081
16280
|
}
|
|
16281
|
+
if (result.warnings.length > 0) {
|
|
16282
|
+
for (const warning of result.warnings)
|
|
16283
|
+
console.log(chalk.yellow(`warning: ${warning}`));
|
|
16284
|
+
}
|
|
16285
|
+
if (globalCoverage) {
|
|
16286
|
+
for (const warning of formatGlobalSourceCoverageWarnings(globalCoverage))
|
|
16287
|
+
console.log(chalk.yellow(`warning: ${warning}`));
|
|
16288
|
+
if (globalCoverage.complete)
|
|
16289
|
+
console.log(chalk.dim(`global source coverage: ${globalCoverage.expectedSlugs.length}/${globalCoverage.expectedSlugs.length} complete`));
|
|
16290
|
+
}
|
|
16082
16291
|
if (result.conflicts.length > 0) {
|
|
16083
16292
|
console.error(chalk.red(`Conflicts: ${result.conflicts.length}. Re-run with --force to overwrite unmanaged files.`));
|
|
16084
16293
|
process.exitCode = 1;
|
|
@@ -16431,6 +16640,7 @@ Keys: ANTHROPIC_API_KEY, OPENAI_API_KEY, EXA_API_KEY, NPM_TOKEN, GITHUB_TOKEN`,
|
|
|
16431
16640
|
}
|
|
16432
16641
|
await ensureGlobalAgentRulesStandardConfig(store);
|
|
16433
16642
|
await ensureDangerousOperationGuardStandardConfig(store);
|
|
16643
|
+
await ensureCodewithSharedTodosStorageStandardConfig(store);
|
|
16434
16644
|
await ensureProjectDashboardStandardConfig(store);
|
|
16435
16645
|
try {
|
|
16436
16646
|
await store.getProfile("my-setup");
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export { PLATFORM_PROFILE_PRESETS, ensurePlatformProfiles } from "./lib/platform
|
|
|
22
22
|
export { PROJECT_DASHBOARD_PROFILE_VARIABLES, PROJECT_DASHBOARD_STANDARD_CONTENT, PROJECT_DASHBOARD_STANDARD_SLUG, ensureProjectDashboardStandardConfig, } from "./lib/project-dashboard-standard.js";
|
|
23
23
|
export { AGENT_OPERATING_RULES_SEMANTIC_POLICY_KEY, AGENT_OPERATING_RULES_SENTINEL_PATTERN, GLOBAL_AGENT_RULES_STANDARD_CONTENT, GLOBAL_AGENT_RULES_STANDARD_SLUG, compareAgentOperatingRulesVersions, ensureGlobalAgentRulesStandardConfig, parseAgentOperatingRulesVersion, resolveAgentOperatingRulesPayload, type AgentOperatingRulesPayload, type AgentOperatingRulesPayloadIntegrity, type AgentOperatingRulesPayloadOrigin, } from "./lib/global-agent-rules-standard.js";
|
|
24
24
|
export { DANGEROUS_OPERATION_GUARD_STANDARD_CONTENT, DANGEROUS_OPERATION_GUARD_STANDARD_SLUG, ensureDangerousOperationGuardStandardConfig, } from "./lib/dangerous-operation-guard-standard.js";
|
|
25
|
+
export { CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE, CODEWITH_SHARED_TODOS_STORAGE_STANDARD_CONTENT, CODEWITH_SHARED_TODOS_STORAGE_STANDARD_SLUG, ensureCodewithSharedTodosStorageStandardConfig, } from "./lib/codewith-shared-todos-storage-standard.js";
|
|
25
26
|
export { syncKnown, syncToDisk, syncProject, diffConfig, detectCategory, detectAgent, detectFormat, KNOWN_CONFIGS, PROJECT_CONFIG_FILES } from "./lib/sync.js";
|
|
26
27
|
export { syncFromDir, syncToDir } from "./lib/sync-dir.js";
|
|
27
28
|
export type { SyncKnownOptions, SyncToDiskOptions, SyncProjectOptions, KnownConfig } from "./lib/sync.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1336,6 +1336,84 @@ async function ensureGlobalAgentRulesStandardConfig(store = resolveConfigStore()
|
|
|
1336
1336
|
return existing;
|
|
1337
1337
|
}
|
|
1338
1338
|
|
|
1339
|
+
// src/lib/codewith-shared-todos-storage-standard.ts
|
|
1340
|
+
var CODEWITH_SHARED_TODOS_STORAGE_STANDARD_SLUG = "codewith-shared-todos-storage-standard";
|
|
1341
|
+
var CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE = "codewith/shared-todos-storage/v1";
|
|
1342
|
+
var CODEWITH_SHARED_TODOS_STORAGE_STANDARD_CONTENT = `# Codewith Shared Todos Storage Standard
|
|
1343
|
+
|
|
1344
|
+
Policy reference: \`${CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE}\`
|
|
1345
|
+
|
|
1346
|
+
## Scope
|
|
1347
|
+
|
|
1348
|
+
- This policy applies to all operational Codewith work: repositories of every
|
|
1349
|
+
name, work projects, research projects, coordinators, delegated workers, and
|
|
1350
|
+
native scheduled or recurring loops. It is not limited to \`open-*\` or
|
|
1351
|
+
\`iapp-*\` repositories.
|
|
1352
|
+
|
|
1353
|
+
## Authoritative Storage
|
|
1354
|
+
|
|
1355
|
+
- Operational Todos state must use the managed shared Todos service.
|
|
1356
|
+
On-box SQLite or file storage is permitted only inside disposable,
|
|
1357
|
+
repository-owned tests using isolated test-controlled paths.
|
|
1358
|
+
- On-box SQLite or file storage must never hold operational tasks, plans, locks or claims,
|
|
1359
|
+
comments, verification evidence, dispatch state, or handoff state. Never
|
|
1360
|
+
fall back to on-box-only storage to keep operational work moving.
|
|
1361
|
+
|
|
1362
|
+
## Pre-Mutation Gate
|
|
1363
|
+
|
|
1364
|
+
- Before any operational Todos mutation, require authoritative Projects
|
|
1365
|
+
linkage and verify from sanitized status or route metadata that Todos resolves
|
|
1366
|
+
to the managed server-backed route. Verification may identify the route class,
|
|
1367
|
+
backend class, and linked project identifiers, but must omit credentials,
|
|
1368
|
+
tokens, DSNs, and full endpoint URLs.
|
|
1369
|
+
- If Projects linkage or server-backed route verification is missing, ambiguous,
|
|
1370
|
+
unavailable, or reports an on-box SQLite or file route, fail closed: do not mutate Todos.
|
|
1371
|
+
Diagnose and repair the owning configuration or service route, re-run the
|
|
1372
|
+
sanitized verification, and report the blockage or repair on the approved
|
|
1373
|
+
operational surface without exposing secrets.
|
|
1374
|
+
|
|
1375
|
+
## Reconciliation
|
|
1376
|
+
|
|
1377
|
+
- Prior on-box-only tasks, plans, comments, locks, verification, dispatch, or
|
|
1378
|
+
handoff evidence are not authoritative. Explicitly reconcile each required
|
|
1379
|
+
record into the Projects-linked shared Todos record, retain bounded provenance
|
|
1380
|
+
identifiers, and independently verify the shared result before treating it as
|
|
1381
|
+
authoritative. Never silently copy, discard, or bless on-box-only evidence.
|
|
1382
|
+
`;
|
|
1383
|
+
async function ensureCodewithSharedTodosStorageStandardConfig(store = resolveConfigStore()) {
|
|
1384
|
+
const input = {
|
|
1385
|
+
name: "Codewith Shared Todos Storage Standard",
|
|
1386
|
+
category: "rules",
|
|
1387
|
+
agent: "codewith",
|
|
1388
|
+
format: "markdown",
|
|
1389
|
+
content: CODEWITH_SHARED_TODOS_STORAGE_STANDARD_CONTENT,
|
|
1390
|
+
kind: "reference",
|
|
1391
|
+
description: "Managed fail-closed shared Todos routing policy for all operational Codewith work",
|
|
1392
|
+
tags: [
|
|
1393
|
+
"codewith",
|
|
1394
|
+
"shared-todos-storage",
|
|
1395
|
+
"server-backed",
|
|
1396
|
+
"projects-linkage",
|
|
1397
|
+
"operational-routing"
|
|
1398
|
+
]
|
|
1399
|
+
};
|
|
1400
|
+
let config;
|
|
1401
|
+
try {
|
|
1402
|
+
const existing = await store.getConfig(CODEWITH_SHARED_TODOS_STORAGE_STANDARD_SLUG);
|
|
1403
|
+
if (existing.content !== input.content || existing.description !== input.description || existing.category !== input.category || existing.agent !== input.agent || existing.format !== input.format || existing.kind !== input.kind || JSON.stringify(existing.tags) !== JSON.stringify(input.tags)) {
|
|
1404
|
+
config = await store.updateConfig(existing.id, input);
|
|
1405
|
+
} else {
|
|
1406
|
+
config = existing;
|
|
1407
|
+
}
|
|
1408
|
+
} catch {
|
|
1409
|
+
config = await store.createConfig(input);
|
|
1410
|
+
}
|
|
1411
|
+
for (const profile of await store.listProfiles()) {
|
|
1412
|
+
await store.addConfigToProfile(profile.id, config.id);
|
|
1413
|
+
}
|
|
1414
|
+
return config;
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1339
1417
|
// src/lib/project-context.ts
|
|
1340
1418
|
import { createHash as createHash2, randomUUID as randomUUID3 } from "crypto";
|
|
1341
1419
|
import { execFileSync } from "child_process";
|
|
@@ -8462,6 +8540,14 @@ function applyAgentOperatingRulesFloor(source, content) {
|
|
|
8462
8540
|
metadata: { ...source.metadata ?? {}, ...payload.metadata, ...floored }
|
|
8463
8541
|
};
|
|
8464
8542
|
}
|
|
8543
|
+
function skippedSource(source, reason) {
|
|
8544
|
+
return {
|
|
8545
|
+
id: source.id,
|
|
8546
|
+
label: source.resolvedLabel,
|
|
8547
|
+
targetProviders: source.targetProviders ?? [],
|
|
8548
|
+
reason
|
|
8549
|
+
};
|
|
8550
|
+
}
|
|
8465
8551
|
function normalizeSources(sources, tool, allowEmptySources) {
|
|
8466
8552
|
const normalized = sources.map((source, index) => {
|
|
8467
8553
|
if (!source.id.trim())
|
|
@@ -8486,14 +8572,17 @@ function normalizeSources(sources, tool, allowEmptySources) {
|
|
|
8486
8572
|
}
|
|
8487
8573
|
return normalized2;
|
|
8488
8574
|
});
|
|
8489
|
-
const
|
|
8575
|
+
const deduplicated = deduplicateSemanticPolicySources(normalized);
|
|
8576
|
+
const ordered = deduplicated.selected.sort((a, b) => SESSION_LAYER_RANK[a.resolvedLayer] - SESSION_LAYER_RANK[b.resolvedLayer] || a.resolvedOrder - b.resolvedOrder || a.id.localeCompare(b.id));
|
|
8490
8577
|
rejectDuplicateSourceSlugs(ordered);
|
|
8491
8578
|
rejectDuplicateRulePaths(ordered);
|
|
8492
|
-
return ordered;
|
|
8579
|
+
return { sources: ordered, skipped: deduplicated.skipped };
|
|
8493
8580
|
}
|
|
8494
8581
|
function deduplicateSemanticPolicySources(sources) {
|
|
8495
8582
|
const selected = [];
|
|
8583
|
+
const skipped = [];
|
|
8496
8584
|
const policySources = new Map;
|
|
8585
|
+
const collapseReason = (winner, key) => `superseded by "${winner.id}": sources declaring the semantic policy ${key} collapse to one so a single instruction home cannot carry two rule-set versions`;
|
|
8497
8586
|
for (const source of sources) {
|
|
8498
8587
|
const sentinel = source.content.match(AGENT_OPERATING_RULES_SENTINEL_PATTERN);
|
|
8499
8588
|
if (!sentinel) {
|
|
@@ -8516,17 +8605,18 @@ function deduplicateSemanticPolicySources(sources) {
|
|
|
8516
8605
|
}
|
|
8517
8606
|
const current = selected[existing.index];
|
|
8518
8607
|
const priorityOrder = semanticPolicySourcePriority(source) - semanticPolicySourcePriority(current);
|
|
8519
|
-
if (priorityOrder < 0)
|
|
8520
|
-
|
|
8521
|
-
if (priorityOrder === 0 && versionOrder <= 0)
|
|
8608
|
+
if (priorityOrder < 0 || priorityOrder === 0 && versionOrder <= 0) {
|
|
8609
|
+
skipped.push(skippedSource(source, collapseReason(current, key)));
|
|
8522
8610
|
continue;
|
|
8611
|
+
}
|
|
8612
|
+
skipped.push(skippedSource(current, collapseReason(source, key)));
|
|
8523
8613
|
selected[existing.index] = {
|
|
8524
8614
|
...source,
|
|
8525
8615
|
resolvedOrder: current.resolvedOrder
|
|
8526
8616
|
};
|
|
8527
8617
|
policySources.set(key, { index: existing.index, version, normalizedContent });
|
|
8528
8618
|
}
|
|
8529
|
-
return selected;
|
|
8619
|
+
return { selected, skipped };
|
|
8530
8620
|
}
|
|
8531
8621
|
function semanticPolicySourcePriority(source) {
|
|
8532
8622
|
let priority = 0;
|
|
@@ -8572,9 +8662,12 @@ function composeSources(sources) {
|
|
|
8572
8662
|
start = i;
|
|
8573
8663
|
}
|
|
8574
8664
|
if (start < 0)
|
|
8575
|
-
return sources;
|
|
8576
|
-
const
|
|
8577
|
-
|
|
8665
|
+
return { sources, skipped: [] };
|
|
8666
|
+
const earlier = sources.slice(0, start);
|
|
8667
|
+
const protectedSources = earlier.filter((source) => source.nonOverridable);
|
|
8668
|
+
const replacer = sources[start];
|
|
8669
|
+
const skipped = earlier.filter((source) => !source.nonOverridable).map((source) => skippedSource(source, `superseded by "${replacer.id}": a replace-merge source discards earlier overridable instruction layers`));
|
|
8670
|
+
return { sources: [...protectedSources, ...sources.slice(start)], skipped };
|
|
8578
8671
|
}
|
|
8579
8672
|
function sectionForSource(source) {
|
|
8580
8673
|
const parts = [
|
|
@@ -8949,7 +9042,14 @@ function planSessionRender(input) {
|
|
|
8949
9042
|
const targetOwner = resolveSessionTargetOwnership(input, { targetHome, targetKind });
|
|
8950
9043
|
const blocked = blockers.length > 0;
|
|
8951
9044
|
const allowEmptySources = input.allowEmptySources === true;
|
|
8952
|
-
const
|
|
9045
|
+
const normalized = normalizeSources(input.sources, input.tool, allowEmptySources);
|
|
9046
|
+
const composed = composeSources(normalized.sources);
|
|
9047
|
+
const orderedSources = composed.sources;
|
|
9048
|
+
const skippedSources = [
|
|
9049
|
+
...input.skippedSources ?? [],
|
|
9050
|
+
...normalized.skipped,
|
|
9051
|
+
...composed.skipped
|
|
9052
|
+
];
|
|
8953
9053
|
if (orderedSources.length === 0 && !allowEmptySources) {
|
|
8954
9054
|
throw new Error("Session render has no instruction sources. Pass --allow-empty-sources only for explicit empty renders.");
|
|
8955
9055
|
}
|
|
@@ -8957,7 +9057,8 @@ function planSessionRender(input) {
|
|
|
8957
9057
|
const env = adapter.envVar && !blocked ? { [adapter.envVar]: targetHome } : {};
|
|
8958
9058
|
const warnings = [
|
|
8959
9059
|
...orderedSources.length === 0 ? ["No instruction sources were provided."] : [],
|
|
8960
|
-
...blockers
|
|
9060
|
+
...blockers,
|
|
9061
|
+
...skippedSources.map((entry) => `Instruction source "${entry.id}" was not rendered: ${entry.reason}`)
|
|
8961
9062
|
];
|
|
8962
9063
|
if (input.providerConfig && input.tool !== "opencode") {
|
|
8963
9064
|
throw new Error("Provider base config is supported only for OpenCode session renders.");
|
|
@@ -9029,7 +9130,7 @@ function planSessionRender(input) {
|
|
|
9029
9130
|
})),
|
|
9030
9131
|
...projectContext ? [projectContext.source] : []
|
|
9031
9132
|
],
|
|
9032
|
-
skippedSources
|
|
9133
|
+
skippedSources,
|
|
9033
9134
|
files: files.map((file) => ({
|
|
9034
9135
|
path: file.path,
|
|
9035
9136
|
relativePath: file.relativePath,
|
|
@@ -9064,6 +9165,7 @@ function planSessionRender(input) {
|
|
|
9064
9165
|
writable: !blocked,
|
|
9065
9166
|
blocked,
|
|
9066
9167
|
blockers,
|
|
9168
|
+
allowEmptySources,
|
|
9067
9169
|
env,
|
|
9068
9170
|
files,
|
|
9069
9171
|
manifest,
|
|
@@ -9086,6 +9188,7 @@ function sourceFromFilePath(path, content, order = 0) {
|
|
|
9086
9188
|
}
|
|
9087
9189
|
function sourceFromConfig(config, order = 0, layer) {
|
|
9088
9190
|
const isAgentOperatingRules = config.slug === GLOBAL_AGENT_RULES_STANDARD_SLUG;
|
|
9191
|
+
const isNonOverridableManagedPolicy = isAgentOperatingRules || config.slug === CODEWITH_SHARED_TODOS_STORAGE_STANDARD_SLUG;
|
|
9089
9192
|
const rules = isAgentOperatingRules ? resolveAgentOperatingRulesPayload(config.content) : null;
|
|
9090
9193
|
return {
|
|
9091
9194
|
id: config.slug,
|
|
@@ -9104,7 +9207,7 @@ function sourceFromConfig(config, order = 0, layer) {
|
|
|
9104
9207
|
configAgent: config.agent
|
|
9105
9208
|
},
|
|
9106
9209
|
metadata: rules ? { ...rules.metadata } : null,
|
|
9107
|
-
nonOverridable:
|
|
9210
|
+
nonOverridable: isNonOverridableManagedPolicy
|
|
9108
9211
|
};
|
|
9109
9212
|
}
|
|
9110
9213
|
function selectProfileConfigsForSessionRender(configs, tool) {
|
|
@@ -10237,6 +10340,7 @@ function applySessionRenderUnlocked(plan, options, coordination) {
|
|
|
10237
10340
|
...files.map((file) => planFileResult(plan, file, targetHome, previousHashes, previousManifest, options)),
|
|
10238
10341
|
...planStaleFileResults(plan, targetHome, previousManifest, currentRelativePaths, options)
|
|
10239
10342
|
];
|
|
10343
|
+
assertNotSilentManagedWipeout(plan, results);
|
|
10240
10344
|
const conflicts = results.filter((result) => result.action === "conflict");
|
|
10241
10345
|
if (conflicts.length > 0) {
|
|
10242
10346
|
return {
|
|
@@ -10246,6 +10350,8 @@ function applySessionRenderUnlocked(plan, options, coordination) {
|
|
|
10246
10350
|
manifestPath,
|
|
10247
10351
|
snapshotPath: null,
|
|
10248
10352
|
env: plan.env,
|
|
10353
|
+
warnings: plan.warnings,
|
|
10354
|
+
skippedSources: plan.manifest.skippedSources,
|
|
10249
10355
|
files: results,
|
|
10250
10356
|
conflicts,
|
|
10251
10357
|
drift
|
|
@@ -10286,6 +10392,8 @@ function applySessionRenderUnlocked(plan, options, coordination) {
|
|
|
10286
10392
|
manifestPath,
|
|
10287
10393
|
snapshotPath,
|
|
10288
10394
|
env: plan.env,
|
|
10395
|
+
warnings: plan.warnings,
|
|
10396
|
+
skippedSources: plan.manifest.skippedSources,
|
|
10289
10397
|
files: results,
|
|
10290
10398
|
conflicts,
|
|
10291
10399
|
drift
|
|
@@ -10809,6 +10917,19 @@ function planFileResult(plan, file, targetHome, previousHashes, previousManifest
|
|
|
10809
10917
|
reason: "existing unmanaged file differs; pass force to overwrite"
|
|
10810
10918
|
};
|
|
10811
10919
|
}
|
|
10920
|
+
function assertNotSilentManagedWipeout(plan, results) {
|
|
10921
|
+
if (plan.allowEmptySources)
|
|
10922
|
+
return;
|
|
10923
|
+
const managedDir = plan.adapter.managedDir;
|
|
10924
|
+
const underManagedDir = (relativePath) => relativePath === managedDir || relativePath.startsWith(`${managedDir}/`);
|
|
10925
|
+
const staleDeletions = results.filter((result) => result.action === "delete" && underManagedDir(result.relativePath));
|
|
10926
|
+
if (staleDeletions.length === 0)
|
|
10927
|
+
return;
|
|
10928
|
+
const managedRetained = results.some((result) => result.action !== "delete" && underManagedDir(result.relativePath));
|
|
10929
|
+
if (managedRetained)
|
|
10930
|
+
return;
|
|
10931
|
+
throw new SessionApplyError(`Session render plan for ${plan.tool} (${plan.adapter.mode}) would delete ${staleDeletions.length} ` + `previously managed file(s) under "${managedDir}" and create or update none there: ` + `${staleDeletions.map((result) => result.relativePath).join(", ")}. ` + "Pass --allow-empty-sources only for explicit empty renders.");
|
|
10932
|
+
}
|
|
10812
10933
|
function planStaleFileResults(plan, targetHome, previousManifest, currentRelativePaths, options) {
|
|
10813
10934
|
if (!previousManifest)
|
|
10814
10935
|
return [];
|
|
@@ -12454,6 +12575,7 @@ export {
|
|
|
12454
12575
|
ensurePlatformProfiles,
|
|
12455
12576
|
ensureGlobalAgentRulesStandardConfig,
|
|
12456
12577
|
ensureDangerousOperationGuardStandardConfig,
|
|
12578
|
+
ensureCodewithSharedTodosStorageStandardConfig,
|
|
12457
12579
|
diffConfig,
|
|
12458
12580
|
detectMachineContext,
|
|
12459
12581
|
detectFormat,
|
|
@@ -12519,6 +12641,9 @@ export {
|
|
|
12519
12641
|
CONFIG_FORMATS,
|
|
12520
12642
|
CONFIG_CATEGORIES,
|
|
12521
12643
|
CONFIG_AGENTS,
|
|
12644
|
+
CODEWITH_SHARED_TODOS_STORAGE_STANDARD_SLUG,
|
|
12645
|
+
CODEWITH_SHARED_TODOS_STORAGE_STANDARD_CONTENT,
|
|
12646
|
+
CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE,
|
|
12522
12647
|
CODEWITH_NATIVE_IMPORTS_ENV,
|
|
12523
12648
|
AGENT_OPERATING_RULES_SENTINEL_PATTERN,
|
|
12524
12649
|
AGENT_OPERATING_RULES_SEMANTIC_POLICY_KEY
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Config } from "../types/index.js";
|
|
2
|
+
import { type ConfigStore } from "../data/config-store.js";
|
|
3
|
+
export declare const CODEWITH_SHARED_TODOS_STORAGE_STANDARD_SLUG = "codewith-shared-todos-storage-standard";
|
|
4
|
+
export declare const CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE = "codewith/shared-todos-storage/v1";
|
|
5
|
+
export declare const CODEWITH_SHARED_TODOS_STORAGE_STANDARD_CONTENT = "# Codewith Shared Todos Storage Standard\n\nPolicy reference: `codewith/shared-todos-storage/v1`\n\n## Scope\n\n- This policy applies to all operational Codewith work: repositories of every\n name, work projects, research projects, coordinators, delegated workers, and\n native scheduled or recurring loops. It is not limited to `open-*` or\n `iapp-*` repositories.\n\n## Authoritative Storage\n\n- Operational Todos state must use the managed shared Todos service.\n On-box SQLite or file storage is permitted only inside disposable,\n repository-owned tests using isolated test-controlled paths.\n- On-box SQLite or file storage must never hold operational tasks, plans, locks or claims,\n comments, verification evidence, dispatch state, or handoff state. Never\n fall back to on-box-only storage to keep operational work moving.\n\n## Pre-Mutation Gate\n\n- Before any operational Todos mutation, require authoritative Projects\n linkage and verify from sanitized status or route metadata that Todos resolves\n to the managed server-backed route. Verification may identify the route class,\n backend class, and linked project identifiers, but must omit credentials,\n tokens, DSNs, and full endpoint URLs.\n- If Projects linkage or server-backed route verification is missing, ambiguous,\n unavailable, or reports an on-box SQLite or file route, fail closed: do not mutate Todos.\n Diagnose and repair the owning configuration or service route, re-run the\n sanitized verification, and report the blockage or repair on the approved\n operational surface without exposing secrets.\n\n## Reconciliation\n\n- Prior on-box-only tasks, plans, comments, locks, verification, dispatch, or\n handoff evidence are not authoritative. Explicitly reconcile each required\n record into the Projects-linked shared Todos record, retain bounded provenance\n identifiers, and independently verify the shared result before treating it as\n authoritative. Never silently copy, discard, or bless on-box-only evidence.\n";
|
|
6
|
+
export declare function ensureCodewithSharedTodosStorageStandardConfig(store?: ConfigStore): Promise<Config>;
|
|
7
|
+
//# sourceMappingURL=codewith-shared-todos-storage-standard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codewith-shared-todos-storage-standard.d.ts","sourceRoot":"","sources":["../../src/lib/codewith-shared-todos-storage-standard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE/E,eAAO,MAAM,2CAA2C,2CAA2C,CAAC;AACpG,eAAO,MAAM,8CAA8C,qCAAqC,CAAC;AAEjG,eAAO,MAAM,8CAA8C,2+DAwC1D,CAAC;AAEF,wBAAsB,8CAA8C,CAClE,KAAK,GAAE,WAAkC,GACxC,OAAO,CAAC,MAAM,CAAC,CA4CjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codewith-shared-todos-storage-standard.test.d.ts","sourceRoot":"","sources":["../../src/lib/codewith-shared-todos-storage-standard.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare const GLOBAL_SOURCE_SLUG_PREFIX = "global-";
|
|
2
|
+
export declare const RETIRED_GLOBAL_SOURCE_TAG = "retired-global-source";
|
|
3
|
+
export interface GlobalSourceCoverageConfig {
|
|
4
|
+
slug: string;
|
|
5
|
+
category: string;
|
|
6
|
+
tags?: string[] | null;
|
|
7
|
+
}
|
|
8
|
+
/** The set of global sources that SHOULD be present in any render that claims
|
|
9
|
+
* global coverage: registered, slug-prefixed `global-`, and not tagged retired. */
|
|
10
|
+
export declare function expectedGlobalSourceSlugs(registryConfigs: readonly GlobalSourceCoverageConfig[]): string[];
|
|
11
|
+
export interface GlobalSourceCoverageResult {
|
|
12
|
+
/** Registered, active global sources — the independent "should exist" side. */
|
|
13
|
+
expectedSlugs: string[];
|
|
14
|
+
/** Slugs actually present on the render plan/manifest being audited. */
|
|
15
|
+
configuredSlugs: string[];
|
|
16
|
+
/** Expected but absent from the render — the actual defect this exists to catch. */
|
|
17
|
+
missingSlugs: string[];
|
|
18
|
+
/** Present on the render but not a currently-expected global source (renamed,
|
|
19
|
+
* retired since the render was built, or simply not a `global-*` slug at all —
|
|
20
|
+
* informational only, never blocking). */
|
|
21
|
+
unexpectedSlugs: string[];
|
|
22
|
+
/** True only when every expected slug is present. */
|
|
23
|
+
complete: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface GlobalSourceCoverageManifest {
|
|
26
|
+
sources: readonly {
|
|
27
|
+
id: string;
|
|
28
|
+
}[];
|
|
29
|
+
skippedSources: readonly {
|
|
30
|
+
id: string;
|
|
31
|
+
}[];
|
|
32
|
+
}
|
|
33
|
+
/** Global config ids the caller supplied to a render, whether they survived
|
|
34
|
+
* composition or were deliberately reported as skipped. A skipped source was
|
|
35
|
+
* configured and accounted for; treating it as absent recreates the exact
|
|
36
|
+
* false-positive this coverage check exists to distinguish from a real gap. */
|
|
37
|
+
export declare function accountedGlobalSourceSlugs(manifest: GlobalSourceCoverageManifest): string[];
|
|
38
|
+
export declare function computeGlobalSourceCoverage(registryConfigs: readonly GlobalSourceCoverageConfig[], configuredSlugs: Iterable<string>): GlobalSourceCoverageResult;
|
|
39
|
+
/** Human-readable warning lines for CLI/manifest output. Empty array means clean. */
|
|
40
|
+
export declare function formatGlobalSourceCoverageWarnings(result: GlobalSourceCoverageResult): string[];
|
|
41
|
+
//# sourceMappingURL=global-source-coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-source-coverage.d.ts","sourceRoot":"","sources":["../../src/lib/global-source-coverage.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,yBAAyB,YAAY,CAAC;AA0BnD,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAEjE,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACxB;AAED;mFACmF;AACnF,wBAAgB,yBAAyB,CACvC,eAAe,EAAE,SAAS,0BAA0B,EAAE,GACrD,MAAM,EAAE,CAMV;AAED,MAAM,WAAW,0BAA0B;IACzC,+EAA+E;IAC/E,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,wEAAwE;IACxE,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,oFAAoF;IACpF,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB;;8CAE0C;IAC1C,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnC,cAAc,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3C;AAED;;;+EAG+E;AAC/E,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,4BAA4B,GACrC,MAAM,EAAE,CAIV;AAED,wBAAgB,2BAA2B,CACzC,eAAe,EAAE,SAAS,0BAA0B,EAAE,EACtD,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,GAChC,0BAA0B,CAe5B;AAED,qFAAqF;AACrF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,0BAA0B,GAAG,MAAM,EAAE,CAK/F"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-source-coverage.test.d.ts","sourceRoot":"","sources":["../../src/lib/global-source-coverage.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type SessionRenderFileRole, type SessionRenderPlan } from "./session-render.js";
|
|
1
|
+
import { type SessionRenderFileRole, type SessionRenderPlan, type SessionSkippedSource } from "./session-render.js";
|
|
2
2
|
export type SessionApplyAction = "create" | "update" | "delete" | "unchanged" | "conflict";
|
|
3
3
|
export interface SessionApplyFileResult {
|
|
4
4
|
path: string;
|
|
@@ -32,6 +32,8 @@ export interface SessionApplyResult {
|
|
|
32
32
|
manifestPath: string;
|
|
33
33
|
snapshotPath: string | null;
|
|
34
34
|
env: Record<string, string>;
|
|
35
|
+
warnings: string[];
|
|
36
|
+
skippedSources: SessionSkippedSource[];
|
|
35
37
|
files: SessionApplyFileResult[];
|
|
36
38
|
conflicts: SessionApplyFileResult[];
|
|
37
39
|
drift: SessionDriftCheck;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-apply.d.ts","sourceRoot":"","sources":["../../src/lib/session-apply.ts"],"names":[],"mappings":"AAiBA,OAAO,EAIL,KAAK,qBAAqB,EAE1B,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"session-apply.d.ts","sourceRoot":"","sources":["../../src/lib/session-apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-render-silent-source-drop.test.d.ts","sourceRoot":"","sources":["../../src/lib/session-render-silent-source-drop.test.ts"],"names":[],"mappings":""}
|
|
@@ -199,6 +199,17 @@ export interface SessionRenderPlan {
|
|
|
199
199
|
writable: boolean;
|
|
200
200
|
blocked: boolean;
|
|
201
201
|
blockers: string[];
|
|
202
|
+
/**
|
|
203
|
+
* Carries the caller's --allow-empty-sources choice from plan-build time into
|
|
204
|
+
* apply time. Apply-time emptiness (a plan that deletes every previously
|
|
205
|
+
* managed file under the adapter's managed directory while creating or
|
|
206
|
+
* updating none — see planStaleFileResults in session-apply.ts) cannot be
|
|
207
|
+
* detected here, because it depends on the previous manifest on disk, which
|
|
208
|
+
* this function never reads. It can only be detected once the stale-file
|
|
209
|
+
* diff is computed in applySessionRenderUnlocked, so the flag has to travel
|
|
210
|
+
* on the plan rather than being re-decided there.
|
|
211
|
+
*/
|
|
212
|
+
allowEmptySources: boolean;
|
|
202
213
|
env: Record<string, string>;
|
|
203
214
|
files: SessionRenderFile[];
|
|
204
215
|
manifest: SessionRenderManifest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-render.d.ts","sourceRoot":"","sources":["../../src/lib/session-render.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-render.d.ts","sourceRoot":"","sources":["../../src/lib/session-render.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAahD,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAEL,0BAA0B,EAI1B,qBAAqB,EAEtB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,uCAAuC,EACvC,6BAA6B,EAC7B,gCAAgC,EAChC,qCAAqC,EACrC,qBAAqB,EACrB,oCAAoC,GACrC,MAAM,8BAA8B,CAAC;AACtC,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,gCAAgC,QAAS,CAAC;AACvD,eAAO,MAAM,yBAAyB,kCAAkC,CAAC;AAEzE,eAAO,MAAM,oBAAoB,oGASvB,CAAC;AAEX,eAAO,MAAM,kCAAkC,2GAKrC,CAAC;AACX,eAAO,MAAM,mCAAmC,0JAItC,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AACtE,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,GAAG,oBAAoB,GAAG,YAAY,GAAG,uBAAuB,GAAG,mBAAmB,CAAC;AACvI,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAClF,MAAM,MAAM,4BAA4B,GAAG,uBAAuB,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;AACzG,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAC3D,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC1F,MAAM,MAAM,uBAAuB,GAAG,cAAc,GAAG,cAAc,GAAG,SAAS,CAAC;AAClF,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,GAAG,SAAS,GAAG,SAAS,CAAC;AAEhF,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,4BAA4B,CAAC;IACrC,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5C,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,4BAA4B,EAAE,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC3C;AAmBD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE;QACN,EAAE,EAAE,OAAO,yBAAyB,CAAC;QACrC,SAAS,EAAE,IAAI,CAAC;QAChB,aAAa,EAAE,CAAC,cAAc,CAAC,CAAC;QAChC,KAAK,EAAE,wBAAwB,GAAG,4BAA4B,CAAC;KAChE,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,cAAc,EAAE,oBAAoB,EAAE,CAAC;IACvC,cAAc,CAAC,EAAE,qBAAqB,CAAC;CACxC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,qBAAqB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,OAAO,qBAAqB,CAAC;IACrC,IAAI,EAAE,iBAAiB,CAAC;IACxB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,uBAAuB,CAAC;IACpC,WAAW,EAAE,kBAAkB,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,uBAAuB,CAAC;QAC/B,KAAK,EAAE,uBAAuB,CAAC;QAC/B,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,KAAK,EAAE,uBAAuB,GAAG,IAAI,CAAC;QACtC,WAAW,EAAE,4BAA4B,EAAE,CAAC;QAC5C,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,cAAc,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,KAAK,EAAE,KAAK,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;YACX,KAAK,EAAE,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,EAAE,CAAC;YAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;SACrB,CAAC,CAAC;QACH,qBAAqB,EAAE,MAAM,CAAC;QAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;QAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;KAC3C,CAAC,CAAC;IACH,cAAc,EAAE,KAAK,CAAC;QACpB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IACH,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,EAAE,qBAAqB,CAAC;QAC5B,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC,CAAC;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,qBAAqB,EAAE,MAAM,CAAC;QAC9B,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,cAAc,CAAC,EAAE;QACf,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,uBAAuB,CAAC;IACpC,WAAW,EAAE,kBAAkB,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;;;;;OASG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,QAAQ,EAAE,qBAAqB,CAAC;IAChC,YAAY,EAAE,iBAAiB,CAAC;IAChC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mBAAmB,CAAC,EAAE,0BAA0B,CAAC;CAClD;AAsBD,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CA8D/E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EAQxD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,EAAE,SAAS,MAAM,EAAsB,CAAC;AAEvF;;;;GAIG;AACH,eAAO,MAAM,sCAAsC,EAAE,SAAS,MAAM,EAInE,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,uBAAuB,EAAE,MAAM,CAYtE,CAAC;AAEF,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,CAkBxF;AAkpBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU1D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUvD;AAsDD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC,EAAE,MAAM,EAAE;IACzH,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,uBAAuB,CAAC;CACrC,GAAG,kBAAkB,CAqDrB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,kBAAkB,GAAG,iBAAiB,CAyK9E;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,wBAAwB,CAUrG;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,CAAC,EAC3E,KAAK,SAAI,EACT,KAAK,CAAC,EAAE,uBAAuB,GAC9B,wBAAwB,CA4B1B;AAED,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,EAAE,iBAAiB,GACtB,6BAA6B,CAoF/B;AA2CD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9E,wBAAwB,EAAE,CAmB5B"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -1196,6 +1196,53 @@ var init_global_agent_rules_standard = __esm(() => {
|
|
|
1196
1196
|
`;
|
|
1197
1197
|
});
|
|
1198
1198
|
|
|
1199
|
+
// src/lib/codewith-shared-todos-storage-standard.ts
|
|
1200
|
+
var CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE = "codewith/shared-todos-storage/v1", CODEWITH_SHARED_TODOS_STORAGE_STANDARD_CONTENT;
|
|
1201
|
+
var init_codewith_shared_todos_storage_standard = __esm(() => {
|
|
1202
|
+
init_config_store();
|
|
1203
|
+
CODEWITH_SHARED_TODOS_STORAGE_STANDARD_CONTENT = `# Codewith Shared Todos Storage Standard
|
|
1204
|
+
|
|
1205
|
+
Policy reference: \`${CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE}\`
|
|
1206
|
+
|
|
1207
|
+
## Scope
|
|
1208
|
+
|
|
1209
|
+
- This policy applies to all operational Codewith work: repositories of every
|
|
1210
|
+
name, work projects, research projects, coordinators, delegated workers, and
|
|
1211
|
+
native scheduled or recurring loops. It is not limited to \`open-*\` or
|
|
1212
|
+
\`iapp-*\` repositories.
|
|
1213
|
+
|
|
1214
|
+
## Authoritative Storage
|
|
1215
|
+
|
|
1216
|
+
- Operational Todos state must use the managed shared Todos service.
|
|
1217
|
+
On-box SQLite or file storage is permitted only inside disposable,
|
|
1218
|
+
repository-owned tests using isolated test-controlled paths.
|
|
1219
|
+
- On-box SQLite or file storage must never hold operational tasks, plans, locks or claims,
|
|
1220
|
+
comments, verification evidence, dispatch state, or handoff state. Never
|
|
1221
|
+
fall back to on-box-only storage to keep operational work moving.
|
|
1222
|
+
|
|
1223
|
+
## Pre-Mutation Gate
|
|
1224
|
+
|
|
1225
|
+
- Before any operational Todos mutation, require authoritative Projects
|
|
1226
|
+
linkage and verify from sanitized status or route metadata that Todos resolves
|
|
1227
|
+
to the managed server-backed route. Verification may identify the route class,
|
|
1228
|
+
backend class, and linked project identifiers, but must omit credentials,
|
|
1229
|
+
tokens, DSNs, and full endpoint URLs.
|
|
1230
|
+
- If Projects linkage or server-backed route verification is missing, ambiguous,
|
|
1231
|
+
unavailable, or reports an on-box SQLite or file route, fail closed: do not mutate Todos.
|
|
1232
|
+
Diagnose and repair the owning configuration or service route, re-run the
|
|
1233
|
+
sanitized verification, and report the blockage or repair on the approved
|
|
1234
|
+
operational surface without exposing secrets.
|
|
1235
|
+
|
|
1236
|
+
## Reconciliation
|
|
1237
|
+
|
|
1238
|
+
- Prior on-box-only tasks, plans, comments, locks, verification, dispatch, or
|
|
1239
|
+
handoff evidence are not authoritative. Explicitly reconcile each required
|
|
1240
|
+
record into the Projects-linked shared Todos record, retain bounded provenance
|
|
1241
|
+
identifiers, and independently verify the shared result before treating it as
|
|
1242
|
+
authoritative. Never silently copy, discard, or bless on-box-only evidence.
|
|
1243
|
+
`;
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1199
1246
|
// node_modules/zod/v3/helpers/util.js
|
|
1200
1247
|
var util, objectUtil, ZodParsedType, getParsedType = (data) => {
|
|
1201
1248
|
const t = typeof data;
|
|
@@ -5662,6 +5709,7 @@ var init_transforms = () => {};
|
|
|
5662
5709
|
var ANTIGRAVITY_RULE_FILE_CHAR_LIMIT = 12000, SESSION_RENDERER_OWNER_ID = "instructions-session-renderer", SESSION_RENDER_PROFILE_ENTRYPOINTS, SESSION_RENDER_OWNED_CONFIG_TARGETS, CODEWITH_FLATTENED_ADAPTER, CODEWITH_NATIVE_ADAPTER, SESSION_TOOL_ADAPTERS, SESSION_RENDER_MANAGED_DIRS, SESSION_RENDER_SHARED_MANAGED_DIRS, SESSION_RENDER_EXCLUSIVE_MANAGED_PATHS, CANONICAL_IDENTITY_EXPORT_PACKAGES;
|
|
5663
5710
|
var init_session_render = __esm(() => {
|
|
5664
5711
|
init_global_agent_rules_standard();
|
|
5712
|
+
init_codewith_shared_todos_storage_standard();
|
|
5665
5713
|
init_project_context();
|
|
5666
5714
|
init_config_agents();
|
|
5667
5715
|
init_transforms();
|
|
@@ -6909,7 +6957,7 @@ var init_sync_dir = __esm(() => {
|
|
|
6909
6957
|
var require_package = __commonJS((exports, module) => {
|
|
6910
6958
|
module.exports = {
|
|
6911
6959
|
name: "@hasna/instructions",
|
|
6912
|
-
version: "0.4.
|
|
6960
|
+
version: "0.4.18",
|
|
6913
6961
|
description: "AI coding agent instruction & configuration manager \u2014 store, version, apply, and share all your AI coding configs. CLI + MCP + HTTP API (instructions-serve) + generated SDK + Dashboard.",
|
|
6914
6962
|
type: "module",
|
|
6915
6963
|
main: "dist/index.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/instructions",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.18",
|
|
4
4
|
"description": "AI coding agent instruction & configuration manager \u2014 store, version, apply, and share all your AI coding configs. CLI + MCP + HTTP API (instructions-serve) + generated SDK + Dashboard.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|