@aiwg/cli 2026.10.9 → 2026.10.11
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/agentic/code/providers/model-capabilities.v1.json +275 -17
- package/bin/aiwg.mjs +8 -0
- package/dist/src/cli/handlers/mc-admission.js +39 -0
- package/dist/src/cli/handlers/mc.js +2 -31
- package/dist/src/cli/handlers/models-help.js +52 -0
- package/dist/src/cli/handlers/models.js +11 -81
- package/dist/src/cli/handlers/sessions.js +198 -15
- package/dist/src/cli/handlers/use-addon-profile.js +72 -0
- package/dist/src/cli/handlers/use.js +203 -234
- package/dist/src/cli/ui.js +1 -0
- package/dist/src/config/aiwg-config.js +38 -184
- package/dist/src/config/cli-help.js +54 -0
- package/dist/src/config/cli.js +5 -69
- package/dist/src/config/config-normalization.js +10 -0
- package/dist/src/config/worker-activation-gate.js +26 -0
- package/dist/src/config/worker-adoption-cli.js +102 -0
- package/dist/src/config/worker-adoption.js +368 -0
- package/dist/src/config/worker-config-digest.js +14 -0
- package/dist/src/config/worker-context.js +337 -0
- package/dist/src/config/worker-group-templates.js +150 -0
- package/dist/src/config/worker-guidance-warning.js +28 -0
- package/dist/src/config/worker-owner-lock.js +152 -0
- package/dist/src/config/worker-parallelism.js +154 -0
- package/dist/src/config/worker-write.js +75 -0
- package/dist/src/decision/telemetry/exporter.js +2 -1
- package/dist/src/decision/telemetry/index.js +1 -0
- package/dist/src/decision/telemetry/mapping.js +43 -0
- package/dist/src/decision/telemetry/otlp-http.js +5 -2
- package/dist/src/decision/telemetry/redaction.js +6 -1
- package/dist/src/decision/telemetry/types.js +3 -0
- package/dist/src/decision/telemetry/worker.js +69 -0
- package/dist/src/lint/rule-activation.js +15 -7
- package/dist/src/lint/runner.js +2 -2
- package/dist/src/mcp/server.mjs +2 -11
- package/dist/src/mcp/stdio-lifecycle.mjs +27 -0
- package/dist/src/mcp/tools/worker-failure-diagnostics.mjs +9 -0
- package/dist/src/mcp/tools/worker-invoke.mjs +114 -16
- package/dist/src/mission-protocol/codecs.js +8 -38
- package/dist/src/mission-protocol/worker-contract-diagnostics.js +62 -0
- package/dist/src/mission-protocol/worker-invocation-types.js +2 -0
- package/dist/src/models/conductor-data-policy.d.mts +8 -0
- package/dist/src/models/conductor-data-policy.mjs +190 -0
- package/dist/src/models/config-loader.js +19 -3
- package/dist/src/models/config-writer.js +27 -0
- package/dist/src/models/model-capabilities.v1.json +275 -17
- package/dist/src/models/provider-policy.js +14 -155
- package/dist/src/models/resolver.js +2 -293
- package/dist/src/models/worker-artifact-binding.mjs +12 -0
- package/dist/src/models/worker-direct-readiness-policy.js +155 -0
- package/dist/src/models/worker-direct-readiness.js +9 -218
- package/dist/src/models/worker-health-readiness.js +105 -26
- package/dist/src/models/worker-installation.mjs +12 -14
- package/dist/src/models/worker-member-references.js +64 -0
- package/dist/src/models/worker-plan.js +317 -0
- package/dist/src/models/worker-selection-policy.js +217 -0
- package/dist/src/models/wrapper-deployment.js +1 -1
- package/dist/src/policy/authorization.js +29 -1
- package/dist/src/process/aiwg-probe-command.d.mts +15 -0
- package/dist/src/process/aiwg-probe-command.mjs +37 -0
- package/dist/src/serve/shared-host-admission-checks.js +116 -0
- package/dist/src/serve/shared-host-scheduler.js +25 -107
- package/dist/src/serve/shared-host-starvation.js +73 -0
- package/dist/src/serve/worker-artifacts.d.mts +4 -0
- package/dist/src/serve/worker-artifacts.mjs +56 -0
- package/dist/src/serve/worker-command-request.js +68 -0
- package/dist/src/serve/worker-invocation-paths.js +144 -0
- package/dist/src/serve/worker-invocation-preparation.js +169 -0
- package/dist/src/serve/worker-invocation.js +24 -291
- package/dist/src/serve/worker-stdin-frame.d.mts +2 -2
- package/dist/src/serve/worker-stdin-frame.mjs +6 -6
- package/dist/src/sessions/adapters/grokbot.js +7 -0
- package/dist/src/sessions/batch-import.js +34 -6
- package/dist/src/sessions/contracts.js +19 -0
- package/dist/src/sessions/coverage-preflight.js +7 -1
- package/dist/src/sessions/fortemi-export-mapping.js +33 -3
- package/dist/src/sessions/host-catalog.js +157 -0
- package/dist/src/sessions/image-blobs.js +141 -0
- package/dist/src/sessions/importer.js +23 -3
- package/dist/src/sessions/index.js +2 -0
- package/dist/src/sessions/refresh.js +25 -2
- package/dist/src/sessions/repository.js +164 -22
- package/dist/src/sessions/workspace-discovery.js +5 -2
- package/dist/src/smiths/context-pipeline/parallelism-section.js +19 -7
- package/package.json +15 -1
- package/schemas/mission-v1.schema.json +20 -19
- package/schemas/models/model-config-compatibility.v1.schema.json +16 -0
- package/tools/agents/providers/claude-post-deploy.mjs +35 -0
- package/tools/agents/providers/claude.mjs +3 -30
- package/tools/agents/providers/codex-post-deploy.mjs +13 -0
- package/tools/agents/providers/codex.mjs +2 -8
- package/tools/agents/providers/conductor-data-guard.mjs +61 -0
- package/tools/agents/providers/rule-delivery.mjs +3 -16
- package/tools/agents/providers/rule-presentation.mjs +38 -0
- package/tools/plugin/package-plugins.mjs +1 -1
- package/tools/ralph-external/lib/claude-adapter.mjs +2 -2
- package/tools/ralph-external/lib/codex-adapter.mjs +3 -3
- package/tools/ralph-external/lib/managed-worker-attempt.mjs +86 -0
- package/tools/ralph-external/lib/muse-adapter.mjs +10 -0
- package/tools/ralph-external/lib/provider-adapter.mjs +11 -260
- package/tools/ralph-external/lib/session-attempt.mjs +85 -0
- package/tools/ralph-external/lib/strict-worker-json.mjs +190 -0
- package/tools/ralph-external/lib/worker-artifacts.mjs +209 -0
- package/tools/ralph-external/lib/worker-context.mjs +237 -0
- package/tools/ralph-external/lib/worker-final.mjs +143 -0
- package/tools/ralph-external/lib/worker-inputs.mjs +55 -0
- package/tools/ralph-external/lib/worker-invocation-ancestry.mjs +132 -0
- package/tools/ralph-external/lib/worker-invocation-processes.mjs +123 -0
- package/tools/ralph-external/lib/worker-isolation-status.mjs +48 -0
- package/tools/ralph-external/lib/worker-isolation.mjs +19 -73
- package/tools/ralph-external/lib/worker-launch-cli.mjs +49 -0
- package/tools/ralph-external/lib/worker-native-sandbox.mjs +83 -0
- package/tools/ralph-external/lib/worker-overflow.mjs +48 -13
- package/tools/ralph-external/lib/worker-retry-evidence.mjs +103 -0
- package/tools/ralph-external/lib/worker-termination.mjs +82 -0
- package/tools/ralph-external/session-launcher.mjs +124 -313
- package/vscode-extension/schemas/aiwg.config.v1.json +161 -2
|
@@ -2,8 +2,10 @@ import { requireFeaturePackage } from '../features/runtime.js';
|
|
|
2
2
|
import { CandidateReviewReceiptSchema, DeletionReceiptSchema, IntelligenceCandidateSchema, PromotionDependencyDecisionSchema, PromotionReceiptSchema, SessionContractError, sha256, } from './contracts.js';
|
|
3
3
|
import { coverageFromBatchRun, } from './batch-contracts.js';
|
|
4
4
|
import { redactSessionText, redactSessionValue, sanitizeSessionEvent, sanitizeNativeExtensions } from './policy.js';
|
|
5
|
+
import { extractBatchEventImages, isImageDigest, } from './image-blobs.js';
|
|
5
6
|
import { effectiveSessionLifecycle } from './lifecycle.js';
|
|
6
7
|
import { deriveSessionAnalytics, } from './analytics.js';
|
|
8
|
+
import { HOST_REFERENCE_TABLE_DDL, } from './host-catalog.js';
|
|
7
9
|
const POLICY_PROVIDER_MIGRATION = 'policy-provider-identity:v2';
|
|
8
10
|
const EVENT_ORIGIN_INTENT_MIGRATION = 'event-origin-intent:v1';
|
|
9
11
|
const VISIBLE_SESSION_PREDICATE = `s.lifecycle != 'tombstoned' AND EXISTS (
|
|
@@ -114,6 +116,17 @@ export class SessionRepository {
|
|
|
114
116
|
CREATE TABLE IF NOT EXISTS session_catalog_meta (
|
|
115
117
|
key TEXT PRIMARY KEY, value TEXT NOT NULL
|
|
116
118
|
);
|
|
119
|
+
-- Content-addressed tool-output image bytes (#3265). One row per
|
|
120
|
+
-- content hash per catalog: repeat imports of identical images share
|
|
121
|
+
-- the row (INSERT OR IGNORE). Events reference blobs by digest and
|
|
122
|
+
-- keep only a bracketed image placeholder (sha256, type, size) in
|
|
123
|
+
-- searchableText, so image bytes never reach FTS. Pre-#3265 rows with
|
|
124
|
+
-- inline bytes are left untouched (no destructive migration).
|
|
125
|
+
CREATE TABLE IF NOT EXISTS session_image_blobs (
|
|
126
|
+
digest TEXT PRIMARY KEY, media_type TEXT NOT NULL,
|
|
127
|
+
byte_length INTEGER NOT NULL, source_locator TEXT,
|
|
128
|
+
source_offset INTEGER, bytes BLOB NOT NULL
|
|
129
|
+
);
|
|
117
130
|
CREATE TABLE IF NOT EXISTS session_analytics_facts (
|
|
118
131
|
fact_id TEXT PRIMARY KEY, workspace_id TEXT NOT NULL,
|
|
119
132
|
session_id TEXT NOT NULL, event_id TEXT NOT NULL,
|
|
@@ -144,6 +157,9 @@ export class SessionRepository {
|
|
|
144
157
|
-- alignment without reading searchable text or event JSON.
|
|
145
158
|
CREATE INDEX IF NOT EXISTS idx_fts_event_id ON session_event_fts_content(c0);
|
|
146
159
|
`);
|
|
160
|
+
// Workspace pointers at account-scoped sessions stored in the host
|
|
161
|
+
// catalog (#3232). References, never copies; legacy copied rows stay.
|
|
162
|
+
this.db.exec(HOST_REFERENCE_TABLE_DDL);
|
|
147
163
|
const deletionReceiptColumns = this.db.prepare('PRAGMA table_info(deletion_receipts)').all().map((row) => String(row.name));
|
|
148
164
|
if (!deletionReceiptColumns.includes('workspace_id')) {
|
|
149
165
|
this.db.exec('ALTER TABLE deletion_receipts ADD COLUMN workspace_id TEXT');
|
|
@@ -479,6 +495,18 @@ export class SessionRepository {
|
|
|
479
495
|
};
|
|
480
496
|
}
|
|
481
497
|
applyImport(batch, checkpoint, publish = true) {
|
|
498
|
+
// Lift inline image payloads out of event text before redaction (#3265):
|
|
499
|
+
// base64 data URLs in text survive redaction and would otherwise be
|
|
500
|
+
// stored inline. Provider image blocks in extensions keep their existing
|
|
501
|
+
// redaction to markers; their bytes are not retained.
|
|
502
|
+
// Idempotent -- placeholder text from an earlier pass matches no image
|
|
503
|
+
// pattern, so importer-extracted batches and direct writers converge.
|
|
504
|
+
// Bytes are parked beside the batch: the redaction pass below walks
|
|
505
|
+
// every value and would flatten Uint8Array into plain objects.
|
|
506
|
+
const extracted = extractBatchEventImages(batch);
|
|
507
|
+
const imageBlobs = extracted.imageBlobs;
|
|
508
|
+
batch = { ...batch, events: extracted.events };
|
|
509
|
+
delete batch.imageBlobs;
|
|
482
510
|
// Guard callers that submit normalized batches directly as well as adapters.
|
|
483
511
|
batch = redactSessionValue({
|
|
484
512
|
...batch,
|
|
@@ -525,6 +553,17 @@ export class SessionRepository {
|
|
|
525
553
|
const merged = mergeSessionAggregate(prior, session);
|
|
526
554
|
this.db.prepare(`UPDATE sessions SET source_digest=?, lifecycle=?, data=? WHERE session_id=?`).run(merged.sourceDigest, merged.lifecycle, JSON.stringify(merged), merged.sessionId);
|
|
527
555
|
}
|
|
556
|
+
// Persist image bytes once per content hash per catalog (#3265).
|
|
557
|
+
// INSERT OR IGNORE keeps the first-seen row when identical images
|
|
558
|
+
// arrive in later batches or replayed records.
|
|
559
|
+
const insertImageBlob = this.db.prepare(`INSERT OR IGNORE INTO session_image_blobs
|
|
560
|
+
(digest, media_type, byte_length, source_locator, source_offset, bytes)
|
|
561
|
+
VALUES (?, ?, ?, ?, ?, ?)`);
|
|
562
|
+
for (const image of imageBlobs) {
|
|
563
|
+
if (!isImageDigest(image.digest))
|
|
564
|
+
continue;
|
|
565
|
+
insertImageBlob.run(image.digest, image.mediaType, image.byteLength, image.locatorClass ?? null, image.offset ?? null, Buffer.from(image.bytes));
|
|
566
|
+
}
|
|
528
567
|
const insertEvent = this.db.prepare(`INSERT OR IGNORE INTO session_events
|
|
529
568
|
(event_id, session_id, source_id, import_run_id, sequence_no, digest, data)
|
|
530
569
|
VALUES (?, ?, ?, ?, ?, ?, ?)`);
|
|
@@ -746,6 +785,49 @@ export class SessionRepository {
|
|
|
746
785
|
listWorkspaceIds() {
|
|
747
786
|
return this.db.prepare('SELECT DISTINCT workspace_id FROM sessions ORDER BY workspace_id').all().map((row) => String(row.workspace_id));
|
|
748
787
|
}
|
|
788
|
+
/**
|
|
789
|
+
* Record a workspace pointer at an account-scoped session stored in the
|
|
790
|
+
* host catalog (#3232). Non-destructive: existing copied rows are left
|
|
791
|
+
* untouched and remain readable.
|
|
792
|
+
*/
|
|
793
|
+
recordHostSessionReference(reference) {
|
|
794
|
+
this.db.prepare(`INSERT INTO session_host_refs
|
|
795
|
+
(provider, native_session_id, session_id, source_id, host_catalog)
|
|
796
|
+
VALUES (?, ?, ?, ?, ?)
|
|
797
|
+
ON CONFLICT(provider, native_session_id) DO UPDATE SET
|
|
798
|
+
session_id=excluded.session_id, source_id=excluded.source_id,
|
|
799
|
+
host_catalog=excluded.host_catalog`).run(reference.provider, reference.nativeSessionId, reference.sessionId, reference.sourceId, reference.hostCatalog);
|
|
800
|
+
}
|
|
801
|
+
listHostSessionReferences() {
|
|
802
|
+
return this.db.prepare(`SELECT provider, native_session_id, session_id, source_id, host_catalog
|
|
803
|
+
FROM session_host_refs ORDER BY provider, native_session_id`).all().map((row) => ({
|
|
804
|
+
provider: String(row.provider),
|
|
805
|
+
nativeSessionId: String(row.native_session_id),
|
|
806
|
+
sessionId: String(row.session_id),
|
|
807
|
+
sourceId: String(row.source_id),
|
|
808
|
+
hostCatalog: String(row.host_catalog),
|
|
809
|
+
}));
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Visible sessions reduced to aggregate identities (plus the internal ids
|
|
813
|
+
* reference recording needs). Aggregate search/analytics over several
|
|
814
|
+
* catalogs dedupe on provider + native session so legacy copied rows
|
|
815
|
+
* count once (#3232).
|
|
816
|
+
*/
|
|
817
|
+
listSessionIdentities(workspaceId) {
|
|
818
|
+
const where = workspaceId
|
|
819
|
+
? `s.workspace_id=? AND ${VISIBLE_SESSION_PREDICATE}`
|
|
820
|
+
: VISIBLE_SESSION_PREDICATE;
|
|
821
|
+
const params = workspaceId ? [workspaceId] : [];
|
|
822
|
+
return this.db.prepare(`SELECT json_extract(s.data, '$.provider') AS provider, s.native_session_id,
|
|
823
|
+
s.session_id, s.source_id
|
|
824
|
+
FROM sessions s WHERE ${where} ORDER BY s.session_id`).all(...params).map((row) => ({
|
|
825
|
+
provider: String(row.provider),
|
|
826
|
+
nativeSessionId: String(row.native_session_id),
|
|
827
|
+
sessionId: String(row.session_id),
|
|
828
|
+
sourceId: String(row.source_id),
|
|
829
|
+
}));
|
|
830
|
+
}
|
|
749
831
|
saveBatchImportRun(run) {
|
|
750
832
|
run = redactSessionValue(run).value;
|
|
751
833
|
const save = this.db.transaction(() => {
|
|
@@ -889,6 +971,62 @@ export class SessionRepository {
|
|
|
889
971
|
ORDER BY e.sequence_no, e.event_id`).all(...(workspaceId ? [sessionId, workspaceId] : [sessionId]))
|
|
890
972
|
.map((row) => JSON.parse(String(row.data)));
|
|
891
973
|
}
|
|
974
|
+
/**
|
|
975
|
+
* Distinct image blobs in this catalog. Identical images share one row
|
|
976
|
+
* per content hash, so this counts unique images, not references (#3265).
|
|
977
|
+
*/
|
|
978
|
+
countImageBlobs() {
|
|
979
|
+
return Number(this.db.prepare('SELECT COUNT(*) AS count FROM session_image_blobs').get()?.count ?? 0);
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Fetch one image blob by content digest. Returns null when the blob is
|
|
983
|
+
* unknown or the digest is malformed -- callers report that as an
|
|
984
|
+
* "unavailable" reference rather than failing the whole read (#3265).
|
|
985
|
+
* Pre-#3265 rows carry inline bytes instead of references and never reach
|
|
986
|
+
* this lookup; they load verbatim through `listEvents`.
|
|
987
|
+
*/
|
|
988
|
+
getImageBlob(digest) {
|
|
989
|
+
if (!isImageDigest(digest))
|
|
990
|
+
return null;
|
|
991
|
+
const row = this.db.prepare(`SELECT digest, media_type, byte_length, source_locator, source_offset, bytes
|
|
992
|
+
FROM session_image_blobs WHERE digest=?`).get(digest);
|
|
993
|
+
if (!row)
|
|
994
|
+
return null;
|
|
995
|
+
return {
|
|
996
|
+
digest: String(row.digest),
|
|
997
|
+
mediaType: String(row.media_type),
|
|
998
|
+
byteLength: Number(row.byte_length),
|
|
999
|
+
sourceLocator: row.source_locator === null ? null : String(row.source_locator),
|
|
1000
|
+
sourceOffset: row.source_offset === null ? null : Number(row.source_offset),
|
|
1001
|
+
bytes: Uint8Array.from(row.bytes),
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Resolve an event's image references against the blob store. Entries
|
|
1006
|
+
* whose bytes are present resolve `available`; entries whose blob is
|
|
1007
|
+
* missing (pruned catalog, legacy reference) resolve `unavailable` with
|
|
1008
|
+
* the reference metadata intact so callers can report it (#3265). Events
|
|
1009
|
+
* without references -- including pre-#3265 inline rows -- resolve to [].
|
|
1010
|
+
*/
|
|
1011
|
+
resolveEventImages(event) {
|
|
1012
|
+
return (event.imageRefs ?? []).map((ref) => {
|
|
1013
|
+
const stored = this.getImageBlob(ref.digest);
|
|
1014
|
+
if (!stored)
|
|
1015
|
+
return { ...ref, status: 'unavailable' };
|
|
1016
|
+
return {
|
|
1017
|
+
digest: ref.digest,
|
|
1018
|
+
mediaType: stored.mediaType,
|
|
1019
|
+
byteLength: stored.byteLength,
|
|
1020
|
+
...(ref.locatorClass !== undefined
|
|
1021
|
+
? { locatorClass: ref.locatorClass }
|
|
1022
|
+
: stored.sourceLocator !== null ? { locatorClass: stored.sourceLocator } : {}),
|
|
1023
|
+
...(ref.offset !== undefined
|
|
1024
|
+
? { offset: ref.offset }
|
|
1025
|
+
: stored.sourceOffset !== null ? { offset: stored.sourceOffset } : {}),
|
|
1026
|
+
status: 'available',
|
|
1027
|
+
};
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
892
1030
|
listTimelineInputs(workspaceId) {
|
|
893
1031
|
return this.db.prepare(`SELECT s.data AS session_data, e.data AS event_data
|
|
894
1032
|
FROM session_events e
|
|
@@ -1168,28 +1306,7 @@ export class SessionRepository {
|
|
|
1168
1306
|
}
|
|
1169
1307
|
analyticsSummary(options) {
|
|
1170
1308
|
const facts = this.listAnalyticsFacts({ ...options, limit: options.limit ?? 5_000 });
|
|
1171
|
-
|
|
1172
|
-
const byStatus = countBy(facts, (fact) => fact.status);
|
|
1173
|
-
const byProvider = countBy(facts, (fact) => fact.provider);
|
|
1174
|
-
const byTool = countBy(facts.filter((fact) => fact.toolName), (fact) => fact.toolName);
|
|
1175
|
-
return {
|
|
1176
|
-
analyticsVersion: '1.0.0',
|
|
1177
|
-
workspaceId: options.workspaceId,
|
|
1178
|
-
totals: {
|
|
1179
|
-
facts: facts.length,
|
|
1180
|
-
sessions: new Set(facts.map((fact) => fact.sessionId)).size,
|
|
1181
|
-
toolCalls: facts.filter((fact) => fact.category === 'tool-call').length,
|
|
1182
|
-
toolFailures: facts.filter((fact) => fact.category === 'tool-result' && fact.status === 'failed').length,
|
|
1183
|
-
escalations: facts.filter((fact) => fact.category === 'escalation').length,
|
|
1184
|
-
hitlDecisions: facts.filter((fact) => fact.category === 'hitl').length,
|
|
1185
|
-
indicators: facts.filter((fact) => fact.category === 'indicator').length,
|
|
1186
|
-
retryGroups: new Set(facts.map((fact) => fact.retryGroupId).filter(Boolean)).size,
|
|
1187
|
-
},
|
|
1188
|
-
byCategory,
|
|
1189
|
-
byStatus,
|
|
1190
|
-
byProvider,
|
|
1191
|
-
byTool,
|
|
1192
|
-
};
|
|
1309
|
+
return summarizeSessionAnalyticsFacts(facts, options.workspaceId);
|
|
1193
1310
|
}
|
|
1194
1311
|
getAnalyticsEvidence(id, workspaceId) {
|
|
1195
1312
|
const row = this.db.prepare(`SELECT f.data AS fact_data, e.data AS event_data
|
|
@@ -1852,6 +1969,31 @@ function canonicalDevinLocator(value) {
|
|
|
1852
1969
|
? `devin-desktop-${value.slice('windsurf-'.length)}`
|
|
1853
1970
|
: value;
|
|
1854
1971
|
}
|
|
1972
|
+
/**
|
|
1973
|
+
* Summarize analytics facts without touching a catalog, so cross-catalog
|
|
1974
|
+
* merges (workspace facts plus referenced host facts, #3232) report the
|
|
1975
|
+
* same shape as a single-catalog summary.
|
|
1976
|
+
*/
|
|
1977
|
+
export function summarizeSessionAnalyticsFacts(facts, workspaceId) {
|
|
1978
|
+
return {
|
|
1979
|
+
analyticsVersion: '1.0.0',
|
|
1980
|
+
workspaceId,
|
|
1981
|
+
totals: {
|
|
1982
|
+
facts: facts.length,
|
|
1983
|
+
sessions: new Set(facts.map((fact) => fact.sessionId)).size,
|
|
1984
|
+
toolCalls: facts.filter((fact) => fact.category === 'tool-call').length,
|
|
1985
|
+
toolFailures: facts.filter((fact) => fact.category === 'tool-result' && fact.status === 'failed').length,
|
|
1986
|
+
escalations: facts.filter((fact) => fact.category === 'escalation').length,
|
|
1987
|
+
hitlDecisions: facts.filter((fact) => fact.category === 'hitl').length,
|
|
1988
|
+
indicators: facts.filter((fact) => fact.category === 'indicator').length,
|
|
1989
|
+
retryGroups: new Set(facts.map((fact) => fact.retryGroupId).filter(Boolean)).size,
|
|
1990
|
+
},
|
|
1991
|
+
byCategory: countBy(facts, (fact) => fact.category),
|
|
1992
|
+
byStatus: countBy(facts, (fact) => fact.status),
|
|
1993
|
+
byProvider: countBy(facts, (fact) => fact.provider),
|
|
1994
|
+
byTool: countBy(facts.filter((fact) => fact.toolName), (fact) => fact.toolName),
|
|
1995
|
+
};
|
|
1996
|
+
}
|
|
1855
1997
|
function countBy(items, key) {
|
|
1856
1998
|
const counts = {};
|
|
1857
1999
|
for (const item of items) {
|
|
@@ -269,10 +269,13 @@ export async function discoverWorkspaceHistories(options) {
|
|
|
269
269
|
// old entries, so a content-digest sourceId (the default above)
|
|
270
270
|
// would churn every re-discovery and break checkpoint continuity.
|
|
271
271
|
// Key it on the conversation id instead, same rationale as the OMP
|
|
272
|
-
// override above.
|
|
272
|
+
// override above. Unlike OMP, the key carries no workspaceId: Grok
|
|
273
|
+
// Bot conversations are account-scoped (#3232), so the same replica
|
|
274
|
+
// must resolve to one host-catalog source no matter which workspace
|
|
275
|
+
// authorizes it; workspace catalogs keep a reference instead of a copy.
|
|
273
276
|
const conversationId = grokbotConversationIdFromLocator(locator);
|
|
274
277
|
if (conversationId) {
|
|
275
|
-
source.sourceId = sha256(['grokbot-native-source-v1',
|
|
278
|
+
source.sourceId = sha256(['grokbot-native-source-v1', conversationId].join('\0'));
|
|
276
279
|
}
|
|
277
280
|
}
|
|
278
281
|
providerSources.push(source);
|
|
@@ -87,7 +87,7 @@ export const MAX_SHOWN_GROUPS = 8;
|
|
|
87
87
|
*/
|
|
88
88
|
function excludedMembers(parallelism, group) {
|
|
89
89
|
const excluded = [];
|
|
90
|
-
for (const member of group.members) {
|
|
90
|
+
for (const member of (group.members ?? [])) {
|
|
91
91
|
if (member.enabled === false)
|
|
92
92
|
excluded.push(`${member.id} (member disabled)`);
|
|
93
93
|
else if (parallelism?.clis?.[member.cli]?.enabled === false)
|
|
@@ -97,15 +97,19 @@ function excludedMembers(parallelism, group) {
|
|
|
97
97
|
}
|
|
98
98
|
function groupSummaries(entries, parallelism) {
|
|
99
99
|
return entries.map(([id, group]) => {
|
|
100
|
-
const roles = [...new Set(group.members.flatMap(m => m.roles ?? []))].join('/');
|
|
101
|
-
const clis = [...new Set(group.members.map(m => m.cli))].join('/');
|
|
102
|
-
const parts = [`${oneLine(id, 64)} (members: ${group.members.length}`];
|
|
100
|
+
const roles = [...new Set((group.members ?? []).flatMap(m => m.roles ?? []))].join('/');
|
|
101
|
+
const clis = [...new Set((group.members ?? []).map(m => m.cli))].join('/');
|
|
102
|
+
const parts = [`${oneLine(id, 64)} (members: ${(group.members ?? []).length}`];
|
|
103
103
|
if (clis)
|
|
104
104
|
parts.push(`clis: ${oneLine(clis, 96)}`);
|
|
105
105
|
if (roles)
|
|
106
106
|
parts.push(`roles: ${oneLine(roles, 96)}`);
|
|
107
107
|
if (group.maxParallel !== undefined)
|
|
108
108
|
parts.push(`maxParallel: ${group.maxParallel}`);
|
|
109
|
+
if (group.efforts)
|
|
110
|
+
parts.push(`efforts: ${oneLine(group.efforts.join('/'), 96)}`);
|
|
111
|
+
if (group.dataPolicy)
|
|
112
|
+
parts.push(`dataPolicy: ${oneLine(JSON.stringify(group.dataPolicy), 240)}`);
|
|
109
113
|
if (group.requiredRoles?.length)
|
|
110
114
|
parts.push(`requiredRoles: ${group.requiredRoles.join('/')}`);
|
|
111
115
|
parts.push('configured');
|
|
@@ -147,13 +151,13 @@ async function observationSummaries(entries, deps) {
|
|
|
147
151
|
`Cached model observations read at ${readAt.toISOString()}; catalog fetchedAt: ${stamp(catalog?.discovery?.fetchedAt)}. Ages are measured at this read and grow afterward. This cache may differ from the resolver's current installation observations; no eligibility read is performed by context generation. Missing or ambiguous observations have unknown age.`,
|
|
148
152
|
'',
|
|
149
153
|
...entries.map(([id, group]) => {
|
|
150
|
-
const observations = group.members.flatMap(member => {
|
|
154
|
+
const observations = (group.members ?? []).flatMap(member => {
|
|
151
155
|
// Mirror the resolver's exact, unambiguous id/API-id lookup per installation.
|
|
152
156
|
const rows = catalog?.discovery?.instances?.[member.cli]?.models
|
|
153
157
|
.filter(row => row.id === member.model || row.apiModelId === member.model) ?? [];
|
|
154
158
|
return rows.length === 1 && rows[0].worker ? [rows[0].worker] : [];
|
|
155
159
|
});
|
|
156
|
-
return `- ${oneLine(id, 64)} cached observations: ${observations.length}/${group.members.length} members; observedAt: ${range(observations.map(row => row.observedAt))}; verifiedAt: ${range(observations.map(row => row.verifiedAt))}.`;
|
|
160
|
+
return `- ${oneLine(id, 64)} cached observations: ${observations.length}/${(group.members ?? []).length} members; observedAt: ${range(observations.map(row => row.observedAt))}; verifiedAt: ${range(observations.map(row => row.verifiedAt))}.`;
|
|
157
161
|
}),
|
|
158
162
|
'',
|
|
159
163
|
];
|
|
@@ -313,7 +317,7 @@ export async function buildParallelismSection(projectPath, deps = {}) {
|
|
|
313
317
|
const hard = healthValue(health, 'hardTimeoutSeconds', 1800);
|
|
314
318
|
lines.push('### Orchestration groups (group dispatch enabled)');
|
|
315
319
|
lines.push('');
|
|
316
|
-
const entries = Object.entries(
|
|
320
|
+
const entries = Object.entries(resolved.groups ?? {});
|
|
317
321
|
if (entries.length > 0) {
|
|
318
322
|
// Slice before summarizing so at most MAX_SHOWN_GROUPS summaries are built.
|
|
319
323
|
const shown = groupSummaries(entries.slice(0, MAX_SHOWN_GROUPS), cfg.parallelism).join(' | ');
|
|
@@ -328,6 +332,14 @@ export async function buildParallelismSection(projectPath, deps = {}) {
|
|
|
328
332
|
lines.push('');
|
|
329
333
|
lines.push(...await observationSummaries(entries.slice(0, MAX_SHOWN_GROUPS), deps));
|
|
330
334
|
const models = await new ConfigLoader(projectPath, { aiwgHome: resolveAiwgHome() }).load(cfg.parallelism);
|
|
335
|
+
for (const [pointer, origins] of Object.entries(models.workerPolicyOrigins ?? {})) {
|
|
336
|
+
if (!pointer.startsWith('/parallelism/groups/') || !pointer.endsWith('/template'))
|
|
337
|
+
continue;
|
|
338
|
+
lines.push(`Template expansion ${oneLine(pointer, 160)}: ${origins.map(origin => `${oneLine(origin.source, 240)}#${oneLine(origin.pointer, 160)} (${origin.digest})`).join(' → ')}. Contributions are retained in workerPolicyOrigins; inherited ceilings remain binding.`);
|
|
339
|
+
}
|
|
340
|
+
const aliases = Object.entries(models.defaults.workerSelection?.roleGuidance ?? {}).filter(([, guidance]) => guidance.baseRole);
|
|
341
|
+
for (const [role, guidance] of aliases)
|
|
342
|
+
lines.push(`Project role ${role} aliases ${guidance.baseRole}; ordered groups: ${guidance.groups.join(', ')}. Resolver eligibility and base-role qualification remain required.`);
|
|
331
343
|
const freshness = models.defaults.workerSelection.freshness;
|
|
332
344
|
lines.push(`Resolver freshness limits from merged model policy: observation warning after ${freshness.warnHours} hours; observation blocked after ${freshness.blockHours} hours; verification blocked after ${freshness.policyDays} days. Future-dated evidence is blocked. Re-resolve before launch; cached ages do not establish eligibility.`);
|
|
333
345
|
lines.push('');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiwg/cli",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.11",
|
|
4
4
|
"description": "Lightweight AIWG CLI for signed, versioned web-backed resources.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,7 +49,17 @@
|
|
|
49
49
|
"tools/ralph-external/session-launcher.mjs",
|
|
50
50
|
"tools/ralph-external/process-monitor.mjs",
|
|
51
51
|
"tools/ralph-external/lib/session-environment.mjs",
|
|
52
|
+
"tools/ralph-external/lib/worker-inputs.mjs",
|
|
53
|
+
"tools/ralph-external/lib/worker-final.mjs",
|
|
54
|
+
"tools/ralph-external/lib/worker-launch-cli.mjs",
|
|
52
55
|
"tools/ralph-external/lib/worker-isolation.mjs",
|
|
56
|
+
"tools/ralph-external/lib/worker-native-sandbox.mjs",
|
|
57
|
+
"tools/ralph-external/lib/worker-isolation-status.mjs",
|
|
58
|
+
"tools/ralph-external/lib/worker-retry-evidence.mjs",
|
|
59
|
+
"tools/ralph-external/lib/worker-termination.mjs",
|
|
60
|
+
"tools/ralph-external/lib/worker-invocation-processes.mjs",
|
|
61
|
+
"tools/ralph-external/lib/worker-invocation-ancestry.mjs",
|
|
62
|
+
"tools/ralph-external/lib/worker-context.mjs",
|
|
53
63
|
"tools/ralph-external/lib/systemd-client.mjs",
|
|
54
64
|
"tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs",
|
|
55
65
|
"tools/ralph-external/lib/launcher-recovery-evidence.mjs",
|
|
@@ -57,7 +67,11 @@
|
|
|
57
67
|
"tools/ralph-external/lib/worker-overflow.mjs",
|
|
58
68
|
"tools/scripts/resource-preflight.mjs",
|
|
59
69
|
"tools/ralph-external/lib/provider-adapter.mjs",
|
|
70
|
+
"tools/ralph-external/lib/strict-worker-json.mjs",
|
|
71
|
+
"tools/ralph-external/lib/session-attempt.mjs",
|
|
72
|
+
"tools/ralph-external/lib/managed-worker-attempt.mjs",
|
|
60
73
|
"tools/ralph-external/lib/worker-health.mjs",
|
|
74
|
+
"tools/ralph-external/lib/worker-artifacts.mjs",
|
|
61
75
|
"tools/ralph-external/lib/claude-adapter.mjs",
|
|
62
76
|
"tools/ralph-external/lib/codex-adapter.mjs",
|
|
63
77
|
"tools/ralph-external/lib/opencode-adapter.mjs",
|
|
@@ -1643,6 +1643,7 @@
|
|
|
1643
1643
|
"type": "object",
|
|
1644
1644
|
"additionalProperties": false,
|
|
1645
1645
|
"properties": {
|
|
1646
|
+
"invocationId": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]{0,51}(?![\\s\\S])" },
|
|
1646
1647
|
"isolation": {
|
|
1647
1648
|
"enum": ["systemd-unit", "native-sandbox"]
|
|
1648
1649
|
},
|
|
@@ -1703,28 +1704,24 @@
|
|
|
1703
1704
|
]
|
|
1704
1705
|
},
|
|
1705
1706
|
"artifacts": {
|
|
1706
|
-
"type": "array",
|
|
1707
|
-
"
|
|
1707
|
+
"type": "array", "maxItems": 16,
|
|
1708
|
+
"contains": { "type": "object", "required": ["location"], "properties": { "location": { "const": "workspace-relative" } } },
|
|
1709
|
+
"minContains": 0, "maxContains": 1,
|
|
1708
1710
|
"items": {
|
|
1709
|
-
"type": "object",
|
|
1710
|
-
"additionalProperties": false,
|
|
1711
|
+
"type": "object", "additionalProperties": false,
|
|
1711
1712
|
"properties": {
|
|
1712
|
-
"name": {
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
},
|
|
1716
|
-
"
|
|
1717
|
-
"type": "string",
|
|
1718
|
-
"maxLength": 1048576
|
|
1719
|
-
},
|
|
1720
|
-
"location": {
|
|
1721
|
-
"const": "run-directory"
|
|
1722
|
-
}
|
|
1713
|
+
"name": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,63}(?![\\s\\S])" },
|
|
1714
|
+
"content": { "type": "string", "maxLength": 1048576 },
|
|
1715
|
+
"location": { "enum": ["run-directory", "workspace-relative"] },
|
|
1716
|
+
"prefix": { "type": "string", "minLength": 1, "maxLength": 256 },
|
|
1717
|
+
"relativePath": { "type": "string", "minLength": 1, "maxLength": 4096 }
|
|
1723
1718
|
},
|
|
1724
|
-
"required": [
|
|
1725
|
-
|
|
1726
|
-
"
|
|
1727
|
-
|
|
1719
|
+
"required": ["name", "content"],
|
|
1720
|
+
"allOf": [{
|
|
1721
|
+
"if": { "required": ["location"], "properties": { "location": { "const": "workspace-relative" } } },
|
|
1722
|
+
"then": { "required": ["prefix", "relativePath"] },
|
|
1723
|
+
"else": { "not": { "anyOf": [{ "required": ["prefix"] }, { "required": ["relativePath"] }] } }
|
|
1724
|
+
}]
|
|
1728
1725
|
}
|
|
1729
1726
|
},
|
|
1730
1727
|
"briefPath": {
|
|
@@ -1871,6 +1868,10 @@
|
|
|
1871
1868
|
"controlEvidence"
|
|
1872
1869
|
],
|
|
1873
1870
|
"allOf": [
|
|
1871
|
+
{
|
|
1872
|
+
"if": { "required": ["artifacts"], "properties": { "artifacts": { "type": "array", "contains": { "type": "object", "required": ["location"], "properties": { "location": { "const": "workspace-relative" } } } } } },
|
|
1873
|
+
"then": { "required": ["invocationId"], "properties": { "transport": { "const": "shell" } } }
|
|
1874
|
+
},
|
|
1874
1875
|
{
|
|
1875
1876
|
"if": {
|
|
1876
1877
|
"properties": {
|
|
@@ -184,6 +184,13 @@
|
|
|
184
184
|
"type": "object",
|
|
185
185
|
"additionalProperties": false,
|
|
186
186
|
"properties": {
|
|
187
|
+
"baseRole": {
|
|
188
|
+
"enum": [
|
|
189
|
+
"efficiency",
|
|
190
|
+
"coding",
|
|
191
|
+
"reasoning"
|
|
192
|
+
]
|
|
193
|
+
},
|
|
187
194
|
"groups": {
|
|
188
195
|
"type": "array",
|
|
189
196
|
"items": {
|
|
@@ -248,6 +255,15 @@
|
|
|
248
255
|
"type": "object",
|
|
249
256
|
"additionalProperties": false,
|
|
250
257
|
"properties": {
|
|
258
|
+
"localOnlyPaths": {
|
|
259
|
+
"type": "array",
|
|
260
|
+
"uniqueItems": true,
|
|
261
|
+
"items": {
|
|
262
|
+
"type": "string",
|
|
263
|
+
"pattern": "^(?!.*(?:^|/)\\.{1,2}(?:/|$))[A-Za-z0-9_.@+,-]+(?:/[A-Za-z0-9_.@+,-]+)*$(?![\\s\\S])"
|
|
264
|
+
},
|
|
265
|
+
"description": "Literal project-relative local-only files or directory subtrees; deployed conductor guards have limited shell coverage."
|
|
266
|
+
},
|
|
251
267
|
"allowedProcessing": {
|
|
252
268
|
"type": "array",
|
|
253
269
|
"items": {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Apply project settings and context after provider file deployment.
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { initializeFrameworkWorkspace, ensureDir } from './base.mjs';
|
|
5
|
+
import { deployHookFile } from './claude.mjs';
|
|
6
|
+
import { deployConductorDataGuard } from './conductor-data-guard.mjs';
|
|
7
|
+
|
|
8
|
+
export async function postDeploy(targetDir, opts) {
|
|
9
|
+
initializeFrameworkWorkspace(targetDir, opts.mode, opts.dryRun, opts.srcRoot);
|
|
10
|
+
await deployConductorDataGuard(targetDir, 'claude', opts);
|
|
11
|
+
|
|
12
|
+
// Claude-specific post-deployment (settings.json, etc.)
|
|
13
|
+
const claudeDir = path.join(targetDir, '.claude');
|
|
14
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
15
|
+
|
|
16
|
+
// If settings.json doesn't exist, create a minimal one
|
|
17
|
+
if (!fs.existsSync(settingsPath) && !opts.dryRun) {
|
|
18
|
+
ensureDir(claudeDir);
|
|
19
|
+
const settings = {
|
|
20
|
+
version: '1.0',
|
|
21
|
+
created: new Date().toISOString(),
|
|
22
|
+
aiwg: {
|
|
23
|
+
enabled: true,
|
|
24
|
+
mode: opts.mode || 'all'
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
|
|
28
|
+
console.log('Created .claude/settings.json');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Hook file architecture: write AIWG.md and wire @AIWG.md into CLAUDE.md
|
|
32
|
+
if (opts.srcRoot && opts.contextFiles !== false) {
|
|
33
|
+
deployHookFile(targetDir, opts);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { postDeploy } from './claude-post-deploy.mjs';
|
|
2
|
+
export { postDeploy };
|
|
1
3
|
import { importImpl } from '../../_resolve-impl.mjs';
|
|
2
4
|
/**
|
|
3
5
|
* Claude Code Provider
|
|
@@ -43,7 +45,6 @@ import {
|
|
|
43
45
|
pruneStaleAiwgSkills,
|
|
44
46
|
computeAllKernelNames,
|
|
45
47
|
parseFrontmatter,
|
|
46
|
-
initializeFrameworkWorkspace,
|
|
47
48
|
filterAgentFiles,
|
|
48
49
|
getAddonAgentFiles,
|
|
49
50
|
getAddonCommandFiles,
|
|
@@ -395,34 +396,6 @@ export function createAgentsMd(target, srcRoot, dryRun) {
|
|
|
395
396
|
// Post-Deployment
|
|
396
397
|
// ============================================================================
|
|
397
398
|
|
|
398
|
-
export async function postDeploy(targetDir, opts) {
|
|
399
|
-
// Initialize framework workspace structure
|
|
400
|
-
initializeFrameworkWorkspace(targetDir, opts.mode, opts.dryRun, opts.srcRoot);
|
|
401
|
-
|
|
402
|
-
// Claude-specific post-deployment (settings.json, etc.)
|
|
403
|
-
const claudeDir = path.join(targetDir, '.claude');
|
|
404
|
-
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
405
|
-
|
|
406
|
-
// If settings.json doesn't exist, create a minimal one
|
|
407
|
-
if (!fs.existsSync(settingsPath) && !opts.dryRun) {
|
|
408
|
-
ensureDir(claudeDir);
|
|
409
|
-
const settings = {
|
|
410
|
-
version: '1.0',
|
|
411
|
-
created: new Date().toISOString(),
|
|
412
|
-
aiwg: {
|
|
413
|
-
enabled: true,
|
|
414
|
-
mode: opts.mode || 'all'
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
|
|
418
|
-
console.log('Created .claude/settings.json');
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
// Hook file architecture: write AIWG.md and wire @AIWG.md into CLAUDE.md
|
|
422
|
-
if (opts.srcRoot && opts.contextFiles !== false) {
|
|
423
|
-
deployHookFile(targetDir, opts);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
399
|
|
|
427
400
|
/**
|
|
428
401
|
* Deploy the AIWG.md hook file and add @AIWG.md directive to CLAUDE.md.
|
|
@@ -444,7 +417,7 @@ function interpolateHookTokens(content, counts, targetDir) {
|
|
|
444
417
|
});
|
|
445
418
|
}
|
|
446
419
|
|
|
447
|
-
function deployHookFile(targetDir, opts) {
|
|
420
|
+
export function deployHookFile(targetDir, opts) {
|
|
448
421
|
const { srcRoot, dryRun, counts } = opts;
|
|
449
422
|
const templatePath = path.join(srcRoot, 'agentic', 'code', 'frameworks', 'sdlc-complete', 'templates', 'project', 'AIWG.md');
|
|
450
423
|
const hookDest = path.join(targetDir, 'AIWG.md');
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Apply project settings and context after provider file deployment.
|
|
2
|
+
import { initializeFrameworkWorkspace } from './base.mjs';
|
|
3
|
+
import { createAgentsMd } from './codex.mjs';
|
|
4
|
+
import { deployConductorDataGuard } from './conductor-data-guard.mjs';
|
|
5
|
+
|
|
6
|
+
export async function postDeploy(targetDir, opts) {
|
|
7
|
+
initializeFrameworkWorkspace(targetDir, opts.mode, opts.dryRun, opts.srcRoot);
|
|
8
|
+
await deployConductorDataGuard(targetDir, 'codex', opts);
|
|
9
|
+
|
|
10
|
+
if (opts.createAgentsMd) {
|
|
11
|
+
if (opts.contextFiles !== false) createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { postDeploy } from './codex-post-deploy.mjs';
|
|
2
|
+
export { postDeploy };
|
|
1
3
|
import { importImpl } from '../../_resolve-impl.mjs';
|
|
2
4
|
/**
|
|
3
5
|
* OpenAI Codex Provider
|
|
@@ -47,7 +49,6 @@ import {
|
|
|
47
49
|
writeFile,
|
|
48
50
|
deployFiles,
|
|
49
51
|
createAgentsMdFromTemplate,
|
|
50
|
-
initializeFrameworkWorkspace,
|
|
51
52
|
getAddonAgentFiles,
|
|
52
53
|
getAddonCommandFiles,
|
|
53
54
|
getAddonSkillDirs,
|
|
@@ -511,13 +512,6 @@ export function generatePluginBundle(targetDir, opts = {}) {
|
|
|
511
512
|
// Post-Deployment
|
|
512
513
|
// ============================================================================
|
|
513
514
|
|
|
514
|
-
export async function postDeploy(targetDir, opts) {
|
|
515
|
-
initializeFrameworkWorkspace(targetDir, opts.mode, opts.dryRun, opts.srcRoot);
|
|
516
|
-
|
|
517
|
-
if (opts.createAgentsMd) {
|
|
518
|
-
if (opts.contextFiles !== false) createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
515
|
|
|
522
516
|
// ============================================================================
|
|
523
517
|
// File Extension
|