@arnilo/prism 0.5.5 → 0.5.6
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/CHANGELOG.md +9 -0
- package/README.md +10 -10
- package/dist/cli-runner.d.ts +8 -1
- package/dist/cli-runner.js +97 -7
- package/dist/extensions.d.ts +18 -1
- package/dist/extensions.js +10 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/docs/cli-rpc.md +15 -1
- package/docs/extension-authoring.md +8 -9
- package/docs/extensions.md +13 -1
- package/docs/graft.md +26 -4
- package/docs/index.md +18 -15
- package/docs/provider-packages.md +20 -20
- package/docs/release-and-install.md +32 -32
- package/docs/wiki.md +46 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## [0.5.6] - 2026-09-09 (plan 069)
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
- **Trusted extension activation**: `activateKernel(kernel)` / `ActivatedKernelConfig` turn a loaded extension kernel into ready-to-spread `AgentConfig` contributions (tools, skills, context, middleware, commands, instruction injectors). No auto-picked single-slot builders/providers.
|
|
5
|
+
- **CLI `--extension`**: repeatable flag loads trusted extension packages — cwd-relative paths (realpath-contained) or `PRISM_EXTENSION_ALLOWLIST` specifiers — and merges their contributions into the run. Modules must export `createExtension()`, a default function, or a default `{name, setup}` object; `--config`/`--resource`/`--tool` stay rejected.
|
|
6
|
+
- **Wiki ingest**: `ingestWikiSource`, `/wiki-ingest` command, `wiki_ingest` tool, and `prism-wiki ingest` stage one external source (text, file, image, PDF; URL via a host `fetchUrl` hook with `assertSsrfAllowedUrl` first) into `raw/ingest/<utc>-<slug>/` as an immutable `source.*` + UTF-8 `extract.md`, then return a Karpathy/OKF filing brief (`metadata.trust: "untrusted_external"`). Compressed PDF/DOCX ride an optional host `extractDocument` hook. Caps: 32 MiB input / 2 MiB extract.
|
|
7
|
+
- **Ingest filing protocol**: `wiki-maintainer` skill + scaffolded `SCHEMA.md` gained the ten-step ingest procedure (catalog-first, integrate-don't-duplicate, OKF v0.2 frontmatter with `sources[].id` footnotes, index/log sync, raw layer read-only, one source per ingest).
|
|
8
|
+
- **Graft graph commands**: `/graft-init` (non-interactive `graft init --no-global`, host `initAgents`/`initYes`), `/graft-build-deep` (`build --deep` with host-configured `deepModel` — provider/model/base-url on argv, `GRAFT_API_KEY` env-only, never on argv, fails closed unconfigured) alongside the keyless `/graft-build`. New `runGraftExit` exit-code runner (build/init are plain text, not JSON) with separate `buildBudgetMs` (120s) / `deepBuildBudgetMs` (600s) / `buildMaxResultBytes` (2 MiB) budgets.
|
|
9
|
+
|
|
1
10
|
## [0.5.5] - 2026-09-08
|
|
2
11
|
|
|
3
12
|
### Fixed
|
package/README.md
CHANGED
|
@@ -162,16 +162,16 @@ printf '{"id":"1","command":"prompt","params":{"input":"Hi"}}\n' \
|
|
|
162
162
|
|
|
163
163
|
| package | version | notes |
|
|
164
164
|
| --- | --- | --- |
|
|
165
|
-
| `@arnilo/prism` | 0.5.
|
|
166
|
-
| `@arnilo/prism-coding-tools` | 0.5.
|
|
167
|
-
| `@arnilo/prism-core` | 0.5.
|
|
168
|
-
| `@arnilo/prism-providers` | 0.5.
|
|
169
|
-
| `@arnilo/prism-acp-agent` | 0.5.
|
|
170
|
-
| `@arnilo/prism-ag-ui` | 0.5.
|
|
171
|
-
| `@arnilo/prism-mcp` | 0.5.
|
|
172
|
-
| `@arnilo/prism-memory` | 0.5.
|
|
173
|
-
| `@arnilo/prism-office` | 0.5.
|
|
174
|
-
| `@arnilo/prism-web-tools` | 0.5.
|
|
165
|
+
| `@arnilo/prism` | 0.5.6 | core — runtime, CLI/RPC, templates, docs |
|
|
166
|
+
| `@arnilo/prism-coding-tools` | 0.5.6 | family — /agent, /security, /document-reader, /openapi, /computer-use-linux, /dev, /caveman, /ponytail, /impeccable subpaths |
|
|
167
|
+
| `@arnilo/prism-core` | 0.5.6 | family — /runtime, /sessions, /governance, /credentials, /enterprise, /work, /validation subpaths |
|
|
168
|
+
| `@arnilo/prism-providers` | 0.5.6 | family — all provider adapters as `/<adapter>` subpaths |
|
|
169
|
+
| `@arnilo/prism-acp-agent` | 0.5.6 | capability — ACP adapter |
|
|
170
|
+
| `@arnilo/prism-ag-ui` | 0.5.6 | capability — AG-UI/A2A/A2UI adapter |
|
|
171
|
+
| `@arnilo/prism-mcp` | 0.5.6 | capability — MCP client/server/OAuth interop |
|
|
172
|
+
| `@arnilo/prism-memory` | 0.5.6 | capability — memory plus /rag, /compaction/*, /graft, /wiki subpaths |
|
|
173
|
+
| `@arnilo/prism-office` | 0.5.6 | capability — /documents, /sheets, /diagrams subpaths |
|
|
174
|
+
| `@arnilo/prism-web-tools` | 0.5.6 | capability — Brave/Exa/Firecrawl plus peer-gated /browser and /obscura subpaths |
|
|
175
175
|
<!-- generated:package-truth:inventory end -->
|
|
176
176
|
|
|
177
177
|
## Scripts
|
package/dist/cli-runner.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Readable, Writable } from "node:stream";
|
|
2
2
|
import type { AgentSession, ContributionFileKind, InstructionInjector, Skill, SystemPromptContribution } from "./contracts.js";
|
|
3
|
+
import { type ActivatedKernelConfig } from "./index.js";
|
|
3
4
|
import type { AgentBundle } from "./node/agent-definitions.js";
|
|
4
5
|
import { type RpcSessionFactory } from "./rpc.js";
|
|
5
6
|
export type CliMode = "print" | "json" | "rpc";
|
|
@@ -35,6 +36,12 @@ export interface CliOptions {
|
|
|
35
36
|
readonly injectorFiles: readonly string[];
|
|
36
37
|
/** Runtime-populated: `--instruction`/`--injector-file` resolved to live injectors. */
|
|
37
38
|
readonly resolvedInstructionInjectors: readonly InstructionInjector[];
|
|
39
|
+
/** Parsed flag: `--extension <specifier>` (repeatable). Loaded via {@link loadCliExtensions}
|
|
40
|
+
* into {@link CliOptions.activatedExtensions} before session creation. */
|
|
41
|
+
readonly extensions: readonly string[];
|
|
42
|
+
/** Runtime-populated (not a parsed flag): activated contributions from `--extension` modules
|
|
43
|
+
* (`kernel.load()` → `activateKernel()`). Merged into `createAgent()` by `agentSession`. */
|
|
44
|
+
readonly activatedExtensions?: ActivatedKernelConfig;
|
|
38
45
|
/** Parsed flag: `--no-agents-md` / `--no-system-md` skip the corresponding auto-load. */
|
|
39
46
|
readonly noAgentsMd: boolean;
|
|
40
47
|
readonly noSystemMd: boolean;
|
|
@@ -71,7 +78,7 @@ export interface CliRuntime {
|
|
|
71
78
|
/** Test injection for `prism dev`: overrides `@arnilo/prism-dev` resolution. */
|
|
72
79
|
readonly loadDevCli?: () => Promise<unknown>;
|
|
73
80
|
}
|
|
74
|
-
export declare const usage = "Usage: prism [--mode print|json|rpc] [-p prompt] [options]\n prism init <dir> [--template <name>] [--list-templates] [--provider <name>] [--with-workflows] [--with-evals] [--force]\n prism providers add <name> [--base-url <url>] [--env-key <name>] [--model <id>] [--force]\n prism dev [--port <n>] [--host <addr>] (loopback inspector; delegates into @arnilo/prism-dev)\n\n\nOptions:\n -p, --prompt <text> Prompt to run in print/json mode\n --provider <name> Provider id from the init provider catalog ('mock' is built in;\n real providers need their @arnilo/prism-providers package +\n credential env var)\n --model <name> Explicit model name\n --session <id> Session id\n --system <text> System instructions\n --context <text> Context text\n --compact <entries> Auto-compaction threshold\n --max-tool-rounds <n> Maximum tool rounds\n --discover Enable workspace contribution discovery (opt-in)\n --discover-kinds <csv> Kinds to discover (default: skill; skill,tool,context,instructions)\n --no-discovery Disable discovery even if --discover is set\n --agents-config <path> App config root holding agents/<name>/AGENT.md bundles (opt-in)\n --no-agents-md Skip auto-loading <workspaceRoot>/AGENTS.md\n --no-system-md Skip auto-loading the global SYSTEM.md layer\n --agents-md-file <path> Read AGENTS.md from <path> instead (trust-gated, source: app)\n --system-md-file <path> Read SYSTEM.md from <path> instead (source: user)\n -h, --help Show this help\n";
|
|
81
|
+
export declare const usage = "Usage: prism [--mode print|json|rpc] [-p prompt] [options]\n prism init <dir> [--template <name>] [--list-templates] [--provider <name>] [--with-workflows] [--with-evals] [--force]\n prism providers add <name> [--base-url <url>] [--env-key <name>] [--model <id>] [--force]\n prism dev [--port <n>] [--host <addr>] (loopback inspector; delegates into @arnilo/prism-dev)\n\n\nOptions:\n -p, --prompt <text> Prompt to run in print/json mode\n --provider <name> Provider id from the init provider catalog ('mock' is built in;\n real providers need their @arnilo/prism-providers package +\n credential env var)\n --model <name> Explicit model name\n --session <id> Session id\n --system <text> System instructions\n --context <text> Context text\n --compact <entries> Auto-compaction threshold\n --max-tool-rounds <n> Maximum tool rounds\n --discover Enable workspace contribution discovery (opt-in)\n --discover-kinds <csv> Kinds to discover (default: skill; skill,tool,context,instructions)\n --no-discovery Disable discovery even if --discover is set\n --extension <specifier> Load a trusted extension module (repeatable). Relative paths load\n from the working directory; package names and absolute paths must\n be listed in PRISM_EXTENSION_ALLOWLIST (comma-separated).\n --agents-config <path> App config root holding agents/<name>/AGENT.md bundles (opt-in)\n --no-agents-md Skip auto-loading <workspaceRoot>/AGENTS.md\n --no-system-md Skip auto-loading the global SYSTEM.md layer\n --agents-md-file <path> Read AGENTS.md from <path> instead (trust-gated, source: app)\n --system-md-file <path> Read SYSTEM.md from <path> instead (source: user)\n -h, --help Show this help\n";
|
|
75
82
|
export declare function parseCliArgs(argv: readonly string[]): CliOptions;
|
|
76
83
|
export declare function runCli(argv: readonly string[], runtime: CliRuntime): Promise<number>;
|
|
77
84
|
export declare function runPromptMode(session: AgentSession, options: CliOptions, stdout: Writable, mode: "print" | "json"): Promise<void>;
|
package/dist/cli-runner.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { basename, dirname } from "node:path";
|
|
1
|
+
import { readFile, realpath } from "node:fs/promises";
|
|
2
|
+
import { basename, dirname, isAbsolute, resolve, sep } from "node:path";
|
|
3
3
|
import process from "node:process";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
4
5
|
import { runPrismDevSubcommand } from "./cli-dev.js";
|
|
5
6
|
import { initUsage, loadProvidersCatalog, runInitCommand } from "./cli-init.js";
|
|
6
7
|
import { providerAddUsage, runProviderAddCommand } from "./cli-provider-add.js";
|
|
7
8
|
import { createContributionRegistries, registerDiscoveredContributions } from "./contributions.js";
|
|
8
|
-
import { createAgent, createContributionRegistry, createMockProvider, providerDone, providerTextDelta, resolveInstructionInjectors, } from "./index.js";
|
|
9
|
+
import { activateKernel, createAgent, createContributionRegistry, createExtensionKernel, createMockProvider, providerDone, providerTextDelta, resolveInstructionInjectors, } from "./index.js";
|
|
9
10
|
import { discoverAgentBundles } from "./node/agent-definitions.js";
|
|
10
11
|
import { discoverContributions } from "./node/contribution-discovery.js";
|
|
11
12
|
import { registerDiscoveredInstructionInjectors } from "./node/instruction-injectors.js";
|
|
@@ -33,6 +34,9 @@ Options:
|
|
|
33
34
|
--discover Enable workspace contribution discovery (opt-in)
|
|
34
35
|
--discover-kinds <csv> Kinds to discover (default: skill; skill,tool,context,instructions)
|
|
35
36
|
--no-discovery Disable discovery even if --discover is set
|
|
37
|
+
--extension <specifier> Load a trusted extension module (repeatable). Relative paths load
|
|
38
|
+
from the working directory; package names and absolute paths must
|
|
39
|
+
be listed in PRISM_EXTENSION_ALLOWLIST (comma-separated).
|
|
36
40
|
--agents-config <path> App config root holding agents/<name>/AGENT.md bundles (opt-in)
|
|
37
41
|
--no-agents-md Skip auto-loading <workspaceRoot>/AGENTS.md
|
|
38
42
|
--no-system-md Skip auto-loading the global SYSTEM.md layer
|
|
@@ -56,11 +60,12 @@ const valueFlags = new Set([
|
|
|
56
60
|
"--agents-md-file",
|
|
57
61
|
"--system-md-file",
|
|
58
62
|
"--agents-config",
|
|
63
|
+
"--extension",
|
|
59
64
|
]);
|
|
60
65
|
const boolFlags = new Set(["--discover", "--no-discovery", "--no-agents-md", "--no-system-md"]);
|
|
61
66
|
// Known-but-inert flags: parsed by earlier builds, never wired to any behavior.
|
|
62
67
|
// Rejected loudly (rather than silently ignored) until a CLI-harness plan wires them.
|
|
63
|
-
const unsupportedFlags = new Set(["--config", "--resource", "--
|
|
68
|
+
const unsupportedFlags = new Set(["--config", "--resource", "--tool"]);
|
|
64
69
|
const ALL_KINDS = ["skill", "tool", "context", "instructions"];
|
|
65
70
|
export function parseCliArgs(argv) {
|
|
66
71
|
let mode = "print";
|
|
@@ -83,6 +88,7 @@ export function parseCliArgs(argv) {
|
|
|
83
88
|
const context = [];
|
|
84
89
|
const instructions = [];
|
|
85
90
|
const injectorFiles = [];
|
|
91
|
+
const extensions = [];
|
|
86
92
|
for (let i = 0; i < argv.length; i += 1) {
|
|
87
93
|
const flag = argv[i];
|
|
88
94
|
if (flag === "-h" || flag === "--help") {
|
|
@@ -163,6 +169,9 @@ export function parseCliArgs(argv) {
|
|
|
163
169
|
case "--agents-config":
|
|
164
170
|
agentsConfig = value;
|
|
165
171
|
break;
|
|
172
|
+
case "--extension":
|
|
173
|
+
extensions.push(value);
|
|
174
|
+
break;
|
|
166
175
|
}
|
|
167
176
|
}
|
|
168
177
|
return {
|
|
@@ -180,6 +189,7 @@ export function parseCliArgs(argv) {
|
|
|
180
189
|
discoverKinds,
|
|
181
190
|
noDiscovery,
|
|
182
191
|
agentsConfig,
|
|
192
|
+
extensions,
|
|
183
193
|
discoveredSkills: [],
|
|
184
194
|
discoveredInjectors: [],
|
|
185
195
|
discoveredAgents: [],
|
|
@@ -317,6 +327,13 @@ export async function runCli(argv, runtime) {
|
|
|
317
327
|
});
|
|
318
328
|
options = { ...options, systemPromptLayers: layers };
|
|
319
329
|
}
|
|
330
|
+
// ponytail: 069 — --extension imports trusted modules only (cwd-contained relative paths,
|
|
331
|
+
// or allow-listed package/absolute specifiers), then activates their array contributions
|
|
332
|
+
// into the CLI agent. Throw policy: a broken extension is a usage error, not a silent skip.
|
|
333
|
+
if (options.extensions.length > 0) {
|
|
334
|
+
const activatedExtensions = await loadCliExtensions(options.extensions);
|
|
335
|
+
options = { ...options, activatedExtensions };
|
|
336
|
+
}
|
|
320
337
|
const session = await (runtime.createSession ?? defaultCreateSession)(options);
|
|
321
338
|
await runPromptMode(session, options, runtime.stdout, mode);
|
|
322
339
|
return 0;
|
|
@@ -386,6 +403,8 @@ function mockSession(options) {
|
|
|
386
403
|
return agentSession({ ...options, providerInstance: createMockProvider([providerTextDelta("Hello"), providerDone()]), modelConfig });
|
|
387
404
|
}
|
|
388
405
|
function agentSession(options) {
|
|
406
|
+
const activated = options.activatedExtensions;
|
|
407
|
+
const skills = activated ? [...options.discoveredSkills, ...activated.skills] : options.discoveredSkills;
|
|
389
408
|
return createAgent({
|
|
390
409
|
model: options.modelConfig,
|
|
391
410
|
provider: options.providerInstance,
|
|
@@ -393,11 +412,13 @@ function agentSession(options) {
|
|
|
393
412
|
// ponytail: Phase 31 — file layers compose with `instructions` (base) via the existing
|
|
394
413
|
// composeSystemPrompt pipeline; rank order (user<package<app<run) is enforced inside.
|
|
395
414
|
...(options.systemPromptLayers.length > 0 ? { systemPrompt: options.systemPromptLayers } : {}),
|
|
396
|
-
// ponytail: discovered skills become selectable via RunOptions.activeSkills (set by runOptions below).
|
|
397
|
-
...(
|
|
415
|
+
// ponytail: discovered/extension skills become selectable via RunOptions.activeSkills (set by runOptions below).
|
|
416
|
+
...(skills.length > 0 ? { skills: createSkillRegistry(skills) } : {}),
|
|
417
|
+
...(activated ? { tools: activated.tools, context: activated.context, middleware: activated.middleware } : {}),
|
|
398
418
|
}).createSession({ id: options.session });
|
|
399
419
|
}
|
|
400
420
|
function runOptions(options) {
|
|
421
|
+
const injectors = [...(options.activatedExtensions?.instructionInjectors ?? []), ...options.resolvedInstructionInjectors];
|
|
401
422
|
return {
|
|
402
423
|
...(options.maxToolRounds !== undefined ? { limits: { maxToolRounds: options.maxToolRounds } } : {}),
|
|
403
424
|
compaction: options.compact ? { thresholdEntries: options.compact } : undefined,
|
|
@@ -405,7 +426,7 @@ function runOptions(options) {
|
|
|
405
426
|
...(options.discover && !options.noDiscovery && options.discoveredSkills.length > 0
|
|
406
427
|
? { activeSkills: options.discoveredSkills.map((s) => s.name) }
|
|
407
428
|
: {}),
|
|
408
|
-
...(
|
|
429
|
+
...(injectors.length > 0 ? { instructionInjectors: injectors } : {}),
|
|
409
430
|
};
|
|
410
431
|
}
|
|
411
432
|
// ponytail: resolve --instruction names against discovered injectors (fail-closed) and load
|
|
@@ -432,6 +453,75 @@ function positiveInt(value, flag) {
|
|
|
432
453
|
throw new CliUsageError(`Invalid value for ${flag}: ${value}`);
|
|
433
454
|
return parsed;
|
|
434
455
|
}
|
|
456
|
+
/** Load `--extension` specifiers into one kernel and activate it. Trust model:
|
|
457
|
+
* the loaded code is trusted host code (same level as the provider factory
|
|
458
|
+
* import in `defaultCreateSession`) — the gates decide WHICH code may load,
|
|
459
|
+
* not sandbox what loaded code does.
|
|
460
|
+
* - Relative `./`/`../` paths: no allow-list needed, but must `realpath`
|
|
461
|
+
* contain inside the working directory (symlinks cannot escape).
|
|
462
|
+
* - Bare package names and absolute paths: exact match in
|
|
463
|
+
* `PRISM_EXTENSION_ALLOWLIST` (comma-separated), evaluated before `import()`.
|
|
464
|
+
* Accepted module shapes: `createExtension()` export, a default function, or
|
|
465
|
+
* a default `{ name, setup }` Extension object. */
|
|
466
|
+
async function loadCliExtensions(specifiers) {
|
|
467
|
+
const allowList = (process.env.PRISM_EXTENSION_ALLOWLIST ?? "")
|
|
468
|
+
.split(",")
|
|
469
|
+
.map((entry) => entry.trim())
|
|
470
|
+
.filter(Boolean);
|
|
471
|
+
const kernel = createExtensionKernel({ errorPolicy: "throw" });
|
|
472
|
+
const extensions = [];
|
|
473
|
+
for (const specifier of specifiers) {
|
|
474
|
+
extensions.push(await importTrustedExtension(specifier, allowList));
|
|
475
|
+
}
|
|
476
|
+
await kernel.load(extensions);
|
|
477
|
+
return activateKernel(kernel);
|
|
478
|
+
}
|
|
479
|
+
async function importTrustedExtension(specifier, allowList) {
|
|
480
|
+
if (specifier.includes("\0"))
|
|
481
|
+
throw new CliUsageError(`Invalid value for --extension: ${specifier}`);
|
|
482
|
+
const relative = specifier.startsWith("./") || specifier.startsWith("../");
|
|
483
|
+
let moduleSpecifier;
|
|
484
|
+
if (relative) {
|
|
485
|
+
const real = await realpath(resolve(specifier)).catch(() => {
|
|
486
|
+
throw new CliUsageError(`--extension "${specifier}" does not exist`);
|
|
487
|
+
});
|
|
488
|
+
const realCwd = await realpath(process.cwd());
|
|
489
|
+
if (real !== realCwd && !real.startsWith(realCwd + sep)) {
|
|
490
|
+
throw new CliUsageError(`--extension "${specifier}" escapes the working directory`);
|
|
491
|
+
}
|
|
492
|
+
moduleSpecifier = pathToFileURL(real).href;
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
if (!allowList.includes(specifier)) {
|
|
496
|
+
throw new CliUsageError(`--extension "${specifier}" is not in PRISM_EXTENSION_ALLOWLIST (package names and absolute paths require it; relative extension paths need ./ or ../)`);
|
|
497
|
+
}
|
|
498
|
+
moduleSpecifier = isAbsolute(specifier) ? pathToFileURL(specifier).href : specifier;
|
|
499
|
+
}
|
|
500
|
+
let mod;
|
|
501
|
+
try {
|
|
502
|
+
mod = await import(moduleSpecifier);
|
|
503
|
+
}
|
|
504
|
+
catch (error) {
|
|
505
|
+
throw new CliUsageError(`--extension "${specifier}" failed to load: ${error instanceof Error ? error.message : String(error)}`);
|
|
506
|
+
}
|
|
507
|
+
return extensionFromModule(mod, specifier);
|
|
508
|
+
}
|
|
509
|
+
function extensionFromModule(mod, specifier) {
|
|
510
|
+
const record = mod;
|
|
511
|
+
if (typeof record.createExtension === "function")
|
|
512
|
+
return record.createExtension();
|
|
513
|
+
if (typeof record.default === "function")
|
|
514
|
+
return record.default();
|
|
515
|
+
if (isExtensionObject(record.default))
|
|
516
|
+
return record.default;
|
|
517
|
+
throw new CliUsageError(`--extension "${specifier}" must export createExtension(), a default function, or a default { name, setup } extension`);
|
|
518
|
+
}
|
|
519
|
+
function isExtensionObject(value) {
|
|
520
|
+
return (typeof value === "object" &&
|
|
521
|
+
value !== null &&
|
|
522
|
+
typeof value.name === "string" &&
|
|
523
|
+
typeof value.setup === "function");
|
|
524
|
+
}
|
|
435
525
|
function write(stream, text) {
|
|
436
526
|
stream.write(text);
|
|
437
527
|
}
|
package/dist/extensions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Extension, ExtensionEvent, ExtensionLifecycleEventName } from "./contracts.js";
|
|
1
|
+
import type { CommandDefinition, ContextProvider, Extension, ExtensionEvent, ExtensionLifecycleEventName, InstructionInjector, Skill, ToolDefinition } from "./contracts.js";
|
|
2
2
|
import { type ContributionRegistries } from "./contributions.js";
|
|
3
3
|
import { type MiddlewareRegistry } from "./middleware.js";
|
|
4
4
|
import { type PermissionPolicy } from "./security.js";
|
|
@@ -40,3 +40,20 @@ export interface ExtensionKernel {
|
|
|
40
40
|
}
|
|
41
41
|
export declare function createExtensionEventBus(options?: Pick<ExtensionKernelOptions, "errorPolicy" | "secrets">): ExtensionEventBus;
|
|
42
42
|
export declare function createExtensionKernel(options?: ExtensionKernelOptions): ExtensionKernel;
|
|
43
|
+
/** Host-owned activation: copy contributed entries into the `createAgent()`
|
|
44
|
+
* fields that accept plain arrays. Contributions stay inert until the host
|
|
45
|
+
* passes the returned fields into runtime config. Array slots only —
|
|
46
|
+
* single-slot builders (`inputBuilder`/`promptBuilder`), `compaction`,
|
|
47
|
+
* `retry`, provider/model selection, and skill activation remain host-owned
|
|
48
|
+
* decisions; `commands` are for host RPC surfaces, not an `AgentConfig` field. */
|
|
49
|
+
export interface ActivatedKernelConfig {
|
|
50
|
+
readonly tools: readonly ToolDefinition[];
|
|
51
|
+
readonly skills: readonly Skill[];
|
|
52
|
+
readonly instructionInjectors: readonly InstructionInjector[];
|
|
53
|
+
readonly context: readonly ContextProvider[];
|
|
54
|
+
/** For host command surfaces (CLI/RPC/UI); not part of `AgentConfig`. */
|
|
55
|
+
readonly commands: readonly CommandDefinition[];
|
|
56
|
+
/** The kernel middleware registry itself; runs only when passed to runtime config. */
|
|
57
|
+
readonly middleware: MiddlewareRegistry;
|
|
58
|
+
}
|
|
59
|
+
export declare function activateKernel(kernel: ExtensionKernel): ActivatedKernelConfig;
|
package/dist/extensions.js
CHANGED
|
@@ -190,6 +190,16 @@ export function createExtensionKernel(options = {}) {
|
|
|
190
190
|
},
|
|
191
191
|
};
|
|
192
192
|
}
|
|
193
|
+
export function activateKernel(kernel) {
|
|
194
|
+
return {
|
|
195
|
+
tools: kernel.registries.tools.list(),
|
|
196
|
+
skills: kernel.registries.skills.list(),
|
|
197
|
+
instructionInjectors: kernel.registries.instructionInjectors.list(),
|
|
198
|
+
context: kernel.registries.contextProviders.list(),
|
|
199
|
+
commands: kernel.registries.commands.list(),
|
|
200
|
+
middleware: kernel.middleware,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
193
203
|
async function assertExtensionLoadPolicy(policy, extension) {
|
|
194
204
|
if (!policy)
|
|
195
205
|
return;
|
package/dist/index.d.ts
CHANGED
|
@@ -43,8 +43,8 @@ export type { EventMultiplexer, EventMultiplexerOptions, EventOverflowInfo, Even
|
|
|
43
43
|
export { createEventMultiplexer, EVENT_MULTIPLEXER_SINGLE_CONSUMER_CODE, EventMultiplexerError } from "./event-multiplexer.js";
|
|
44
44
|
export type { ExecutionAction, ExecutionDecision, ExecutionPolicy, ExecutionRisk } from "./execution-policy.js";
|
|
45
45
|
export { applyExecutionDecision, assertExecutionAllowed, checkExecution, ExecutionDeniedError } from "./execution-policy.js";
|
|
46
|
-
export type { ExtensionErrorPolicy, ExtensionEventBus, ExtensionEventHandler, ExtensionKernel, ExtensionKernelOptions, ExtensionLoadPolicy, LoadedExtension, } from "./extensions.js";
|
|
47
|
-
export { createExtensionEventBus, createExtensionKernel } from "./extensions.js";
|
|
46
|
+
export type { ActivatedKernelConfig, ExtensionErrorPolicy, ExtensionEventBus, ExtensionEventHandler, ExtensionKernel, ExtensionKernelOptions, ExtensionLoadPolicy, LoadedExtension, } from "./extensions.js";
|
|
47
|
+
export { activateKernel, createExtensionEventBus, createExtensionKernel } from "./extensions.js";
|
|
48
48
|
export type { MemoryRunFeedbackStoreOptions, PrepareRunFeedbackOptions, RunFeedbackLimits, RunFeedbackRun, RunFeedbackRunResolver, } from "./feedback.js";
|
|
49
49
|
export { createMemoryRunFeedbackStore, prepareRunFeedback, RunFeedbackError, requireRunFeedbackOwnership, runFeedbackPageLimit, } from "./feedback.js";
|
|
50
50
|
export type { ApplyFieldPolicyOptions, AuditFieldRedaction, AuditFieldRedactorLike, AuditFieldRedactorOptions, FieldPolicy, FieldPolicyAction, FieldPolicyDecision, FieldPolicyInput, ProtectedFieldPolicyOptions, } from "./field-policy.js";
|
|
@@ -119,5 +119,5 @@ export { trimTrailingSlashes } from "./trim-trailing-slashes.js";
|
|
|
119
119
|
export type { ResolvedUseCaseModel, ResolveUseCaseModelInput, UseCaseModelBinding, } from "./use-case-model.js";
|
|
120
120
|
export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
|
|
121
121
|
export declare const name = "prism";
|
|
122
|
-
export declare const version = "0.5.
|
|
122
|
+
export declare const version = "0.5.6";
|
|
123
123
|
export declare const description = "Agent harness for AI providers, agents, sessions, and tools.";
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ export { createDelegatedAgentStep, DelegatedAgentStepError, MAX_DELEGATED_AGENT_
|
|
|
22
22
|
export { acceptDeviceChunk, assertDeviceAdmit, DEFAULT_DEVICE_MAX_CHUNK_BYTES, DEFAULT_DEVICE_MAX_CONCURRENT_SESSIONS, DevicePolicyError, HARD_DEVICE_MAX_CHUNK_BYTES, HARD_DEVICE_MAX_CONCURRENT_SESSIONS, redactDeviceTelemetry, resolveDevicePolicy, runDevicePolicyConformance, } from "./devices.js";
|
|
23
23
|
export { createEventMultiplexer, EVENT_MULTIPLEXER_SINGLE_CONSUMER_CODE, EventMultiplexerError } from "./event-multiplexer.js";
|
|
24
24
|
export { applyExecutionDecision, assertExecutionAllowed, checkExecution, ExecutionDeniedError } from "./execution-policy.js";
|
|
25
|
-
export { createExtensionEventBus, createExtensionKernel } from "./extensions.js";
|
|
25
|
+
export { activateKernel, createExtensionEventBus, createExtensionKernel } from "./extensions.js";
|
|
26
26
|
export { createMemoryRunFeedbackStore, prepareRunFeedback, RunFeedbackError, requireRunFeedbackOwnership, runFeedbackPageLimit, } from "./feedback.js";
|
|
27
27
|
export { ALLOW_FIELD_POLICY, applyFieldPolicy, createAuditFieldRedactor, createProtectedFieldPolicy, FIELD_POLICY_LIMITS, FieldPolicyError, } from "./field-policy.js";
|
|
28
28
|
export { assertGuardrailsAllowed, GuardrailError, MAX_GUARDRAIL_CONCURRENCY, runGuardrails } from "./guardrails.js";
|
|
@@ -66,6 +66,6 @@ export { createToolParameterValidator, createToolRegistry, dispatchToolCall, fil
|
|
|
66
66
|
export { trimTrailingSlashes } from "./trim-trailing-slashes.js";
|
|
67
67
|
export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
|
|
68
68
|
export const name = "prism";
|
|
69
|
-
export const version = "0.5.
|
|
69
|
+
export const version = "0.5.6";
|
|
70
70
|
export const description = "Agent harness for AI providers, agents, sessions, and tools.";
|
|
71
71
|
//# sourceMappingURL=index.js.map
|
package/docs/cli-rpc.md
CHANGED
|
@@ -10,7 +10,7 @@ The `prism` bin is a thin adapter over `AgentSession` plus a tiny project scaffo
|
|
|
10
10
|
- `prism init <dir>`: create a minimal TypeScript project with one selected provider, `.env.example`, and one offline mock test.
|
|
11
11
|
- `prism dev`: boot the loopback dev inspector over the scaffolded agent (delegates into `@arnilo/prism-coding-tools/dev` when resolvable; plan 040 Task 4).
|
|
12
12
|
|
|
13
|
-
It does not add a TUI, app tools, provider globals,
|
|
13
|
+
It does not add a TUI, app tools, provider globals, resource discovery, or credential storage, and it never auto-discovers extension packages — `--extension` loads only explicitly named modules (relative paths inside the working directory, or allow-listed package/absolute specifiers). `init` uses Node standard-library filesystem APIs and checked-in templates only — no interactive prompts or template-engine dependency.
|
|
14
14
|
|
|
15
15
|
## Live CLI journey (plans/064 Task 5)
|
|
16
16
|
|
|
@@ -115,6 +115,7 @@ Manifests of the negotiation are simple: the agent is loaded from the scaffold c
|
|
|
115
115
|
| `--discover` | Opt-in workspace contribution discovery (`SKILL.md`/`manifest.json`). Never auto-activates or imports. |
|
|
116
116
|
| `--discover-kinds <csv>` | Kinds to scan; defaults to `skill`. Accepts `skill,tool,context,instructions`. |
|
|
117
117
|
| `--no-discovery` | Hard-disable discovery even if `--discover` is set. |
|
|
118
|
+
| `--extension <specifier>` | Load a trusted extension module (repeatable). Relative `./`/`../` paths must realpath-contain inside the working directory; package names and absolute paths must exactly match an entry in `PRISM_EXTENSION_ALLOWLIST` (comma-separated), checked before `import()`. See the extension loading section below. |
|
|
118
119
|
| `--agents-config <path>` | App config root holding `agents/<name>/AGENT.md` bundles (opt-in). Envelopes only; the host resolves them via `resolveAgentBundle`. The CLI never defaults to the user's home directory. |
|
|
119
120
|
| `--instruction <name>` | Select a registered/discovered instruction injector (repeatable). `--instruction false` disables injectors for the run. Names resolve fail-closed. |
|
|
120
121
|
| `--injector-file <path>` | Load a markdown file as a static `every_turn` injector (repeatable). |
|
|
@@ -124,6 +125,19 @@ Manifests of the negotiation are simple: the agent is loaded from the scaffold c
|
|
|
124
125
|
| `--system-md-file <path>` | Read SYSTEM.md from `<path>` instead — user-owned, `source: "user"` (Phase 31). |
|
|
125
126
|
| `--help` | Print usage. |
|
|
126
127
|
|
|
128
|
+
### Extension loading (`--extension`)
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# cwd-relative trusted module (no allow-list needed)
|
|
132
|
+
prism --provider mock --extension ./my-ext.js -p "hello"
|
|
133
|
+
|
|
134
|
+
# package name or absolute path requires an exact allow-list entry
|
|
135
|
+
PRISM_EXTENSION_ALLOWLIST=@acme/prism-foo \
|
|
136
|
+
prism --provider mock --extension @acme/prism-foo -p "hello"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Each module must export `createExtension()`, a default function, or a default `{ name, setup }` extension. Loaded modules are trusted host code (same trust level as the provider factory import) — the gates decide which code may load, not what loaded code may do: relative paths fail closed on realpath escape (symlinks cannot leave the working directory), package/absolute specifiers fail closed without an allow-list entry, and a broken or wrong-shaped module is a usage error, not a silent skip. Registered contributions activate through `activateKernel` into the run's agent (tools, skills, injectors, context, middleware); extension skills follow the normal fail-closed skill activation (`RunOptions.activeSkills`). There is no npm marketplace, no `plugin.json`, and no MCP auto-start.
|
|
140
|
+
|
|
127
141
|
RPC request envelope:
|
|
128
142
|
|
|
129
143
|
```ts
|
|
@@ -96,12 +96,11 @@ The `contributed` set is what the extension registered. The `active` set is what
|
|
|
96
96
|
|
|
97
97
|
```ts
|
|
98
98
|
import {
|
|
99
|
+
activateKernel,
|
|
99
100
|
createAgent,
|
|
100
101
|
createExtensionKernel,
|
|
101
102
|
createMockProvider,
|
|
102
103
|
createContributionRegistries,
|
|
103
|
-
createSkillRegistry,
|
|
104
|
-
createToolRegistry,
|
|
105
104
|
providerDone,
|
|
106
105
|
type Extension,
|
|
107
106
|
} from "@arnilo/prism";
|
|
@@ -139,19 +138,18 @@ const registries = createContributionRegistries({ duplicate: "error" });
|
|
|
139
138
|
const kernel = createExtensionKernel({ registries, errorPolicy: "throw" });
|
|
140
139
|
await kernel.load([extension]);
|
|
141
140
|
|
|
142
|
-
// Host activation:
|
|
143
|
-
const
|
|
144
|
-
const skill = kernel.registries.skills.resolve("acme.brief");
|
|
141
|
+
// Host activation: copy the array slots; filter/narrow before createAgent() as needed.
|
|
142
|
+
const activated = activateKernel(kernel);
|
|
145
143
|
const provider = createMockProvider([providerDone()]);
|
|
146
144
|
|
|
147
145
|
const agent = createAgent({
|
|
148
146
|
model: { provider: "mock", model: "demo" },
|
|
149
147
|
provider,
|
|
150
|
-
tools:
|
|
151
|
-
skills:
|
|
152
|
-
context:
|
|
148
|
+
tools: activated.tools,
|
|
149
|
+
skills: activated.skills,
|
|
150
|
+
context: activated.context,
|
|
153
151
|
promptBuilder: kernel.registries.promptBuilders.resolve("acme.prompt"),
|
|
154
|
-
middleware:
|
|
152
|
+
middleware: activated.middleware,
|
|
155
153
|
});
|
|
156
154
|
|
|
157
155
|
await agent.createSession().run("Use the Acme extension.", { activeSkills: ["acme.brief"] });
|
|
@@ -166,6 +164,7 @@ await agent.createSession().run("Use the Acme extension.", { activeSkills: ["acm
|
|
|
166
164
|
- `registerSkill()` contributes instructions only. Referenced `toolNames` are checked against host-active tools when the skill is activated.
|
|
167
165
|
- `registerAuthMethod()` and `registerCredentialResolver()` must not contain resolved credential values. Use descriptors/resolvers; the host resolves secrets at the provider/request edge.
|
|
168
166
|
- Middleware from `api.use()` runs only when the host passes `kernel.middleware` into runtime configuration.
|
|
167
|
+
- `activateKernel(kernel)` copies the array slots (`tools`, `skills`, `instructionInjectors`, `context`, `commands`) plus `kernel.middleware` in one call; filter the returned arrays before `createAgent()` when the host wants narrower selection.
|
|
169
168
|
- Provider packages, provider request policies, system prompt contributions, instruction injectors, builders, strategies, commands, store factories, resource loaders, settings providers, and credential resolvers are all inert until host code selects or invokes them.
|
|
170
169
|
|
|
171
170
|
### Host driver hooks (opt-in)
|
package/docs/extensions.md
CHANGED
|
@@ -42,6 +42,7 @@ createExtensionEventBus(options?: { errorPolicy?: "event" | "throw"; secrets?: r
|
|
|
42
42
|
- `kernel.events.on(type, handler)` registers ordered event handlers and returns an unsubscribe function.
|
|
43
43
|
- `kernel.events.emit(event)` calls matching handlers in registration order.
|
|
44
44
|
- `kernel.middleware.run(hook, value)` runs matching middleware in registration order.
|
|
45
|
+
- `activateKernel(kernel)` copies the `createAgent()` array slots into one config: `{ tools, skills, instructionInjectors, context, commands, middleware }`. Contributions stay inert until the host passes them into runtime config; single-slot builders, `compaction`/`retry`, provider/model selection, and skill activation remain host-owned decisions.
|
|
45
46
|
- With default `errorPolicy: "event"`, setup/listener/middleware errors become `extension_error` events with redacted `ErrorInfo`.
|
|
46
47
|
- With `errorPolicy: "throw"`, setup/listener/middleware errors reject/throw.
|
|
47
48
|
|
|
@@ -57,7 +58,7 @@ createExtensionEventBus(options?: { errorPolicy?: "event" | "throw"; secrets?: r
|
|
|
57
58
|
## Implementation example
|
|
58
59
|
|
|
59
60
|
```ts
|
|
60
|
-
import { createAgent, createExtensionKernel, type Extension } from "@arnilo/prism";
|
|
61
|
+
import { activateKernel, createAgent, createExtensionKernel, type Extension } from "@arnilo/prism";
|
|
61
62
|
|
|
62
63
|
const extension: Extension = {
|
|
63
64
|
name: "demo-extension",
|
|
@@ -96,6 +97,17 @@ console.log(kernel.registries.skills.resolve("brief").name); // contributed only
|
|
|
96
97
|
console.log(kernel.registries.agents.resolve("demo").name); // contributed only; host must create/select before runtime use
|
|
97
98
|
console.log(kernel.registries.systemPromptContributions.resolve("demo-prompt").text); // contributed only; host must select before prompt use
|
|
98
99
|
await kernel.middleware.run("provider_request", { metadata: {} });
|
|
100
|
+
|
|
101
|
+
// Host activation: copy the array slots into createAgent() fields.
|
|
102
|
+
const activated = activateKernel(kernel);
|
|
103
|
+
const agent = createAgent({
|
|
104
|
+
model: { provider: "mock", model: "demo" },
|
|
105
|
+
tools: activated.tools,
|
|
106
|
+
skills: activated.skills,
|
|
107
|
+
instructionInjectors: activated.instructionInjectors,
|
|
108
|
+
context: activated.context,
|
|
109
|
+
middleware: activated.middleware,
|
|
110
|
+
});
|
|
99
111
|
```
|
|
100
112
|
|
|
101
113
|
## Extension and configuration notes
|
package/docs/graft.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
`@arnilo/prism-memory/graft` is an optional subpath that wires [nanonets/graft](https://github.com/nanonets/graft) — a repository context-graph CLI (`graft/` directory, INDEX.md orientation, symbol-level wiring graph) — into Prism contribution contracts.
|
|
6
6
|
|
|
7
|
-
It registers six pull tools backed by the graft CLI (`--json`, argv-safe), a push-mode retrieval-pack context provider plus first-turn orientation injector carried on the `graft` skill, commands (`graft`, `graft-build`, `graft-check`, `graft-viz`), and an edit-watch middleware that computes blast radius after mutating tool calls. Import is inert; a missing graft CLI fails closed at `setup` with a bounded redacted error.
|
|
7
|
+
It registers six pull tools backed by the graft CLI (`--json`, argv-safe), a push-mode retrieval-pack context provider plus first-turn orientation injector carried on the `graft` skill, commands (`graft`, `graft-build`, `graft-build-deep`, `graft-check`, `graft-viz`, `graft-init`), and an edit-watch middleware that computes blast radius after mutating tool calls. Import is inert; a missing graft CLI fails closed at `setup` with a bounded redacted error.
|
|
8
8
|
|
|
9
9
|
## When to use it
|
|
10
10
|
|
|
@@ -32,6 +32,9 @@ Zero-code alternative (L0): hosts can skip this package entirely and let agents
|
|
|
32
32
|
| `maxPromptChars` | `number` | no | Prompts longer than this never become ask argv (default 4096). |
|
|
33
33
|
| `allowUpstreamTelemetry` | `boolean` | no | Default false → children run with `DO_NOT_TRACK=1`. |
|
|
34
34
|
| `providerEnv` | `Record<string, string>` | no | Explicit graft provider settings (`GRAFT_API_KEY`, …). Never inherited from host env; only `GRAFT_*` keys reach the child. |
|
|
35
|
+
| `deepModel` | `{ provider: "openai" \| "anthropic" \| "litellm" \| "orcarouter", model: string, apiKey: string, baseUrl?: string }` | no | Model for `graft build --deep` (Graft's own LLM client — **Prism's `Provider` is not Graft's LLM**; they have different protocols). Merged over `providerEnv` as `GRAFT_PROVIDER`/`GRAFT_MODEL`/`GRAFT_API_KEY`/`GRAFT_BASE_URL`; wins on conflict. |
|
|
36
|
+
| `initAgents` / `initYes` / `initWireMcp` | `readonly string[]` / `boolean` / `boolean` | no | `graft init` configuration: agent ids for `--agents`, `--yes`, and whether to wire graft MCP servers (default off — Prism provides its own graft surfaces). `graft-init` refuses to spawn without `initAgents` or `initYes` (the child has no TTY). |
|
|
37
|
+
| `buildBudgetMs` / `deepBuildBudgetMs` / `buildMaxResultBytes` | `number` | no | Budgets for graph builds: structural `build`/`init` default 120000 ms, `--deep` default 600000 ms (the LLM pass over the graph), stdout cap 2 MiB. Ask/grep stay on `retrievalBudgetMs`. |
|
|
35
38
|
| `editToolNames` | `readonly string[]` | no | Tools triggering blast-radius lookup. Default `write`, `edit`, `move`. |
|
|
36
39
|
| `quietStartup`, `hideStatus` | `boolean` | no | Suppress startup status events / status reporting. |
|
|
37
40
|
| `appendEntry` | `(entry, opts?) => Promise<void>` | yes | Host session append (OM attach pattern). |
|
|
@@ -41,7 +44,20 @@ Pull tools (mode includes `pull`): `graft_ask`, `graft_grep`, `graft_callers`, `
|
|
|
41
44
|
|
|
42
45
|
Push surfaces (mode includes `push`): skill `graft` carrying context provider `graft-context` (per-turn pointers-only pack, gated: ≥12-char prompt, dedup by seen node ids, 32 KiB block ceiling) and instruction injector `graft-orient` (`first_turn`, byte-capped INDEX.md cut + staleness banner).
|
|
43
46
|
|
|
44
|
-
Registered commands: `graft` (`status` \| `build` \| `check` \| `viz` dispatch), plus `graft-build`, `graft-check`, `graft-viz` aliases.
|
|
47
|
+
Registered commands: `graft` (`status` \| `build` [deep:true] \| `check` \| `viz` \| `init` dispatch), plus `graft-build`, `graft-build-deep`, `graft-check`, `graft-viz`, `graft-init` aliases.
|
|
48
|
+
|
|
49
|
+
### Graph builds and init
|
|
50
|
+
|
|
51
|
+
- `/graft-build` — structural rebuild via `graft build` (tree-sitter pass, no API key, plain-text progress — no `JSON.parse` on this surface).
|
|
52
|
+
- `/graft-build-deep` — `graft build --deep --provider <> --model <> [--base-url <>]` using the host's `deepModel`. Without a configured model it errors before spawning. `GRAFT_API_KEY` rides in the child env, never on argv.
|
|
53
|
+
- `/graft-init` — `graft init --no-global` (never writes user-level state), default `--no-mcp --no-hooks --no-statusline` (opt in via `initWireMcp`), plus `--agents <id>` per `initAgents` and `--yes` when `initYes`. Requires one of the two; non-interactive by design.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# structural, no key
|
|
57
|
+
/graft-build
|
|
58
|
+
# deep — host-configured model
|
|
59
|
+
e.g. /graft-build-deep
|
|
60
|
+
```
|
|
45
61
|
|
|
46
62
|
## Outputs / response / events
|
|
47
63
|
|
|
@@ -49,7 +65,8 @@ Registered commands: `graft` (`status` \| `build` \| `check` \| `viz` dispatch),
|
|
|
49
65
|
| --- | --- |
|
|
50
66
|
| `createGraftExtension(options)` | Returns an inert `Extension` until `kernel.load([...])`; emits `graft:loaded` on setup. |
|
|
51
67
|
| `resolveGraftCli(options)` | Fail-closed CLI resolution (`explicit` → command+argv, `peer-bin` → node + manifest bin). |
|
|
52
|
-
| `runGraftJson(cli, argv, options)` / `childEnv(options)` / `childTimeoutMs` / `DEFAULT_MAX_RESULT_BYTES` |
|
|
68
|
+
| `runGraftJson(cli, argv, options)` / `runGraftExit(cli, argv, options)` / `childEnv(options)` / `childTimeoutMs` / `DEFAULT_MAX_RESULT_BYTES` | Budgeted runners for hosts building custom surfaces — JSON surfaces (`check`/`ask`) vs exit-code surfaces (`build`/`init`). |
|
|
69
|
+
| `deepProviderEnv(deepModel, providerEnv)` | `deepModel` merged over `providerEnv`, filtered to `GRAFT_*`. |
|
|
53
70
|
| `readBoundedFile` / `redactPaths` / `GraftResolveError` | Bounded-read and redaction helpers. |
|
|
54
71
|
|
|
55
72
|
Events: `graft:status` (check/build outcomes), `graft:dirty` (post-edit, repo-relative path + optional `staleCountEstimate`), `graft:loaded` (mode + cliKind metadata).
|
|
@@ -92,12 +109,15 @@ await kernel.load([
|
|
|
92
109
|
packageRoot: "./vendor/graft-checkout",
|
|
93
110
|
mode: "both",
|
|
94
111
|
quietStartup: true,
|
|
112
|
+
deepModel: { provider: "anthropic", model: "claude-sonnet-4-5", apiKey: process.env.ANTHROPIC_API_KEY! },
|
|
113
|
+
initAgents: ["codex"],
|
|
95
114
|
appendEntry: async (entry, options) => store.append(entry, options),
|
|
96
115
|
getEntries: async () => store.list("s1"),
|
|
97
116
|
}),
|
|
98
117
|
]);
|
|
99
118
|
// Pull: dispatch graft_ask/… tools. Push: runs assemble the skill-carried
|
|
100
119
|
// provider + graft-orient injector. Edits: middleware emits graft:dirty.
|
|
120
|
+
// /graft-build-deep runs graft's own LLM pass; /graft-init wires codex, --no-global.
|
|
101
121
|
```
|
|
102
122
|
|
|
103
123
|
## Extension and configuration notes
|
|
@@ -110,7 +130,9 @@ await kernel.load([
|
|
|
110
130
|
|
|
111
131
|
## Security and performance notes
|
|
112
132
|
|
|
113
|
-
- Telemetry default-off: children always get `DO_NOT_TRACK=1` unless `allowUpstreamTelemetry` is true; child env is fixed-base — host env vars are never inherited, and only explicit `GRAFT_*` keys from `providerEnv` pass through. Route secrets like `GRAFT_API_KEY` through the host's credential resolution when populating `providerEnv`.
|
|
133
|
+
- Telemetry default-off: children always get `DO_NOT_TRACK=1` unless `allowUpstreamTelemetry` is true; child env is fixed-base — host env vars are never inherited, and only explicit `GRAFT_*` keys from `providerEnv`/`deepModel` pass through. Route secrets like `GRAFT_API_KEY` through the host's credential resolution when populating `deepModel`/`providerEnv`. `deepModel`'s API key reaches the child via env only — never on argv (no `--api-key` flag exists in the surface), so it cannot leak through `ps` or logs.
|
|
134
|
+
- Build/init commands are budgeted separately from retrieval (`buildBudgetMs`, `deepBuildBudgetMs`, `buildMaxResultBytes`); deep builds fail closed without a configured model instead of spawning unconfigured.
|
|
135
|
+
- `graft-init` always passes `--no-global` — it never writes user-level agent state; MCP/hook/statusline wiring stays off unless the host opts in via `initWireMcp`.
|
|
114
136
|
- Upstream output is untrusted: stdout capped (`maxResultBytes`), prompts capped (`maxPromptChars`), injected packs bounded (32 KiB), orientation cut byte-capped (8 KiB); error paths are logged redacted (absolute paths/home dirs).
|
|
115
137
|
- Every CLI call is wall-clock-budgeted (`retrievalBudgetMs`, minus fixed overhead for the timeout math) and every failure degrades silently: pull tools return structured errors, the push pack contributes nothing, edit-watch passes the tool result through untouched.
|
|
116
138
|
- No background workers; state persists through two CAS appends per turn at most (freshness patch, seen-set/saved-tokens update).
|
package/docs/index.md
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
Prism is a TypeScript/Node.js agent harness. Hosts own providers, tools, credentials, storage, and behavior; Prism supplies contracts, registries, events, and replaceable runtime primitives.
|
|
4
4
|
|
|
5
|
-
## Current line (0.5.
|
|
5
|
+
## Current line (0.5.6)
|
|
6
6
|
|
|
7
|
+
- **Trusted extension activation**: `activateKernel(kernel)` returns ready-to-spread `AgentConfig` contributions; CLI loads allow-listed `--extension` packages (plan 069).
|
|
8
|
+
- **Wiki ingest**: `/wiki-ingest` + `ingestWikiSource` stage text/file/image/PDF (and URLs via a host `fetchUrl` hook) into `raw/ingest/` with an OKF filing brief (plan 069).
|
|
9
|
+
- **Graft graph commands**: `/graft-init`, `/graft-build`, `/graft-build-deep` (host-configured `deepModel`, key env-only) (plan 069).
|
|
7
10
|
- **Run limits**: HARD caps are request/response bytes only; policy axes accept `null` (plan 067).
|
|
8
11
|
- **Tool-result fold**: content-only `ToolResult`s fold into `tool_result.result` (0.5.3).
|
|
9
12
|
- **Stream token coalesce**: adjacent text/thinking deltas merge on persist (0.5.2).
|
|
10
13
|
- **Provider request construction**: kernel session/cache/thinking defaults; hosts overlay (0.5.1).
|
|
11
|
-
- **10 publishable packages** at current **0.5.
|
|
14
|
+
- **10 publishable packages** at current **0.5.6** lockstep — inventory below.
|
|
12
15
|
|
|
13
16
|
## Public contracts
|
|
14
17
|
|
|
@@ -85,7 +88,7 @@ Prism is a TypeScript/Node.js agent harness. Hosts own providers, tools, credent
|
|
|
85
88
|
- [Versioned prompt registry](prompt-registry.md): immutable content-hashed prompt assets with durable stores and bounded diff.
|
|
86
89
|
- [Instruction injection](instruction-injection.md): package injectors layer redacted instructions without granting capabilities.
|
|
87
90
|
- [Context and skills](context-and-skills.md): ordered context providers, progressive skill disclosure, fail-closed activation.
|
|
88
|
-
- [LLM Wiki](wiki.md): optional knowledge compiler emitting OKF bundles with on-device hybrid search.
|
|
91
|
+
- [LLM Wiki](wiki.md): optional knowledge compiler emitting OKF bundles, with `/wiki-ingest` raw staging (text, file, image, or URL via a host `fetchUrl` hook) and on-device hybrid search.
|
|
89
92
|
- [Retrieval-augmented generation](rag.md): bounded source lifecycle, hybrid retrieval, reranking, citations, inert injection.
|
|
90
93
|
|
|
91
94
|
## Tools
|
|
@@ -150,7 +153,7 @@ Prism is a TypeScript/Node.js agent harness. Hosts own providers, tools, credent
|
|
|
150
153
|
## CLI/RPC
|
|
151
154
|
|
|
152
155
|
- [Dev inspector](dev-inspector.md): loopback-only local playground over a configured agent; `prism dev` composition.
|
|
153
|
-
- [CLI/RPC](cli-rpc.md): print/json modes, LF-delimited RPC, `prism init` scaffold, provider scaffolding.
|
|
156
|
+
- [CLI/RPC](cli-rpc.md): print/json modes, LF-delimited RPC, `prism init` scaffold, provider scaffolding, allow-listed `--extension` activation.
|
|
154
157
|
- [Workflows](workflows.md): typed bounded DAG orchestration with durable suspend/resume, schedules, sagas.
|
|
155
158
|
|
|
156
159
|
## Security and credentials
|
|
@@ -176,7 +179,7 @@ Prism is a TypeScript/Node.js agent harness. Hosts own providers, tools, credent
|
|
|
176
179
|
|
|
177
180
|
- [Caveman behavior integration](caveman.md): upstream Caveman skills with injector, persistence, and progressive catalog.
|
|
178
181
|
- [Ponytail behavior integration](ponytail.md): upstream Ponytail skills with injector and peer resolution; opt-in.
|
|
179
|
-
- [Graft context-graph integration](graft.md): graft CLI pull tools, retrieval-pack context provider, blast-radius middleware.
|
|
182
|
+
- [Graft context-graph integration](graft.md): graft CLI pull tools, retrieval-pack context provider, blast-radius middleware, and `/graft-init` / `/graft-build` / `/graft-build-deep` commands (host-configured `deepModel`).
|
|
180
183
|
- [Impeccable behavior integration](impeccable.md): upstream Impeccable skill behind `load_skill`; host supplies the compiled `SKILL.md`.
|
|
181
184
|
|
|
182
185
|
## Release and install
|
|
@@ -195,14 +198,14 @@ The generated inventory below derives from [`scripts/package-truth.json`](../scr
|
|
|
195
198
|
|
|
196
199
|
| package | version | notes |
|
|
197
200
|
| --- | --- | --- |
|
|
198
|
-
| `@arnilo/prism` | 0.5.
|
|
199
|
-
| `@arnilo/prism-coding-tools` | 0.5.
|
|
200
|
-
| `@arnilo/prism-core` | 0.5.
|
|
201
|
-
| `@arnilo/prism-providers` | 0.5.
|
|
202
|
-
| `@arnilo/prism-acp-agent` | 0.5.
|
|
203
|
-
| `@arnilo/prism-ag-ui` | 0.5.
|
|
204
|
-
| `@arnilo/prism-mcp` | 0.5.
|
|
205
|
-
| `@arnilo/prism-memory` | 0.5.
|
|
206
|
-
| `@arnilo/prism-office` | 0.5.
|
|
207
|
-
| `@arnilo/prism-web-tools` | 0.5.
|
|
201
|
+
| `@arnilo/prism` | 0.5.6 | core — runtime, CLI/RPC, templates, docs |
|
|
202
|
+
| `@arnilo/prism-coding-tools` | 0.5.6 | family — /agent, /security, /document-reader, /openapi, /computer-use-linux, /dev, /caveman, /ponytail, /impeccable subpaths |
|
|
203
|
+
| `@arnilo/prism-core` | 0.5.6 | family — /runtime, /sessions, /governance, /credentials, /enterprise, /work, /validation subpaths |
|
|
204
|
+
| `@arnilo/prism-providers` | 0.5.6 | family — all provider adapters as `/<adapter>` subpaths |
|
|
205
|
+
| `@arnilo/prism-acp-agent` | 0.5.6 | capability — ACP adapter |
|
|
206
|
+
| `@arnilo/prism-ag-ui` | 0.5.6 | capability — AG-UI/A2A/A2UI adapter |
|
|
207
|
+
| `@arnilo/prism-mcp` | 0.5.6 | capability — MCP client/server/OAuth interop |
|
|
208
|
+
| `@arnilo/prism-memory` | 0.5.6 | capability — memory plus /rag, /compaction/*, /graft, /wiki subpaths |
|
|
209
|
+
| `@arnilo/prism-office` | 0.5.6 | capability — /documents, /sheets, /diagrams subpaths |
|
|
210
|
+
| `@arnilo/prism-web-tools` | 0.5.6 | capability — Brave/Exa/Firecrawl plus peer-gated /browser and /obscura subpaths |
|
|
208
211
|
<!-- generated:package-truth:inventory end -->
|
|
@@ -25,26 +25,26 @@ Do not use provider packages as a package manager, credential store, env loader,
|
|
|
25
25
|
|
|
26
26
|
| adapter package | version |
|
|
27
27
|
| --- | --- |
|
|
28
|
-
| `@arnilo/prism-providers/ai-sdk` | 0.5.
|
|
29
|
-
| `@arnilo/prism-providers/alibaba` | 0.5.
|
|
30
|
-
| `@arnilo/prism-providers/anthropic` | 0.5.
|
|
31
|
-
| `@arnilo/prism-providers/azure` | 0.5.
|
|
32
|
-
| `@arnilo/prism-providers/bedrock` | 0.5.
|
|
33
|
-
| `@arnilo/prism-providers/clinepass` | 0.5.
|
|
34
|
-
| `@arnilo/prism-providers/commandcode` | 0.5.
|
|
35
|
-
| `@arnilo/prism-providers/deepseek` | 0.5.
|
|
36
|
-
| `@arnilo/prism-providers/google` | 0.5.
|
|
37
|
-
| `@arnilo/prism-providers/hyper` | 0.5.
|
|
38
|
-
| `@arnilo/prism-providers/kimi` | 0.5.
|
|
39
|
-
| `@arnilo/prism-providers/model-discovery` | 0.5.
|
|
40
|
-
| `@arnilo/prism-providers/neuralwatt` | 0.5.
|
|
41
|
-
| `@arnilo/prism-providers/ollama` | 0.5.
|
|
42
|
-
| `@arnilo/prism-providers/openai` | 0.5.
|
|
43
|
-
| `@arnilo/prism-providers/opencode-go` | 0.5.
|
|
44
|
-
| `@arnilo/prism-providers/openrouter` | 0.5.
|
|
45
|
-
| `@arnilo/prism-providers/vertex` | 0.5.
|
|
46
|
-
| `@arnilo/prism-providers/xai` | 0.5.
|
|
47
|
-
| `@arnilo/prism-providers/zai` | 0.5.
|
|
28
|
+
| `@arnilo/prism-providers/ai-sdk` | 0.5.6 |
|
|
29
|
+
| `@arnilo/prism-providers/alibaba` | 0.5.6 |
|
|
30
|
+
| `@arnilo/prism-providers/anthropic` | 0.5.6 |
|
|
31
|
+
| `@arnilo/prism-providers/azure` | 0.5.6 |
|
|
32
|
+
| `@arnilo/prism-providers/bedrock` | 0.5.6 |
|
|
33
|
+
| `@arnilo/prism-providers/clinepass` | 0.5.6 |
|
|
34
|
+
| `@arnilo/prism-providers/commandcode` | 0.5.6 |
|
|
35
|
+
| `@arnilo/prism-providers/deepseek` | 0.5.6 |
|
|
36
|
+
| `@arnilo/prism-providers/google` | 0.5.6 |
|
|
37
|
+
| `@arnilo/prism-providers/hyper` | 0.5.6 |
|
|
38
|
+
| `@arnilo/prism-providers/kimi` | 0.5.6 |
|
|
39
|
+
| `@arnilo/prism-providers/model-discovery` | 0.5.6 |
|
|
40
|
+
| `@arnilo/prism-providers/neuralwatt` | 0.5.6 |
|
|
41
|
+
| `@arnilo/prism-providers/ollama` | 0.5.6 |
|
|
42
|
+
| `@arnilo/prism-providers/openai` | 0.5.6 |
|
|
43
|
+
| `@arnilo/prism-providers/opencode-go` | 0.5.6 |
|
|
44
|
+
| `@arnilo/prism-providers/openrouter` | 0.5.6 |
|
|
45
|
+
| `@arnilo/prism-providers/vertex` | 0.5.6 |
|
|
46
|
+
| `@arnilo/prism-providers/xai` | 0.5.6 |
|
|
47
|
+
| `@arnilo/prism-providers/zai` | 0.5.6 |
|
|
48
48
|
<!-- generated:package-truth:providers end -->
|
|
49
49
|
|
|
50
50
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
## What it does
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
Prism's current **0.5.x** line has **10 publishable manifests**: the root `@arnilo/prism` core package plus **9 workspace packages** — **19 provider adapters** (19 provider adapter subpaths inside the `@arnilo/prism-providers` family), 3 `prism-*` family/profile packages, and 6 capability packages. (Generated by `node scripts/package-truth.mjs` → `scripts/package-truth.json` — the manifest-derived single source for counts, provider membership, umbrella closures, and profile closures.) The last lockstep cut was 0.3.0; Decision B now publishes changed packages independently inside `^0.3.0` — the plan 039 changed-package cut moved root `@arnilo/prism` and every plan-035+ changed package to **0.3.1**, and the plan 050 changed-package cut moved root plus four changed packages to **0.3.2**; the plan 041-044 changed-package cut moves root to **0.3.3** with `@arnilo/prism-memory@0.3.2` (composite recall scoring), `@arnilo/prism-evals@0.3.1` (trace-to-dataset curation), the three session-store packages at **0.3.1** (run-ledger `promptVersion` provenance), and the initial `@arnilo/prism-prompts@0.0.1` (independent opt-in, outside `prism-all`); plan 054 consolidation then folded `@arnilo/prism-browser` and `@arnilo/prism-obscura` into the `@arnilo/prism-web-tools` family as `/browser` and `/obscura` subpaths, folded `@arnilo/prism-rag`, both compaction strategies, `@arnilo/prism-graft`, and `@arnilo/prism-wiki` into the `@arnilo/prism-memory` family as `/rag`, `/compaction/llm`, `/compaction/observational-memory`, `/graft`, and `/wiki` subpaths (deleting the `@arnilo/prism-compaction` profile), and folded all 17 `@arnilo/prism-provider-*` packages into the `@arnilo/prism-providers` family as `/<adapter>` subpaths (Azure/Bedrock/Vertex stop being special all-only manifests); independent publication continues inside `^0.3.0` ranges (which satisfy 0.3.1, 0.3.2, and 0.3.3). This page describes how they are packed, what each tarball contains, how to install them, the required non-optional **caret** `@arnilo/prism@^0.5.
|
|
8
|
+
Prism's current **0.5.x** line has **10 publishable manifests**: the root `@arnilo/prism` core package plus **9 workspace packages** — **19 provider adapters** (19 provider adapter subpaths inside the `@arnilo/prism-providers` family), 3 `prism-*` family/profile packages, and 6 capability packages. (Generated by `node scripts/package-truth.mjs` → `scripts/package-truth.json` — the manifest-derived single source for counts, provider membership, umbrella closures, and profile closures.) The last lockstep cut was 0.3.0; Decision B now publishes changed packages independently inside `^0.3.0` — the plan 039 changed-package cut moved root `@arnilo/prism` and every plan-035+ changed package to **0.3.1**, and the plan 050 changed-package cut moved root plus four changed packages to **0.3.2**; the plan 041-044 changed-package cut moves root to **0.3.3** with `@arnilo/prism-memory@0.3.2` (composite recall scoring), `@arnilo/prism-evals@0.3.1` (trace-to-dataset curation), the three session-store packages at **0.3.1** (run-ledger `promptVersion` provenance), and the initial `@arnilo/prism-prompts@0.0.1` (independent opt-in, outside `prism-all`); plan 054 consolidation then folded `@arnilo/prism-browser` and `@arnilo/prism-obscura` into the `@arnilo/prism-web-tools` family as `/browser` and `/obscura` subpaths, folded `@arnilo/prism-rag`, both compaction strategies, `@arnilo/prism-graft`, and `@arnilo/prism-wiki` into the `@arnilo/prism-memory` family as `/rag`, `/compaction/llm`, `/compaction/observational-memory`, `/graft`, and `/wiki` subpaths (deleting the `@arnilo/prism-compaction` profile), and folded all 17 `@arnilo/prism-provider-*` packages into the `@arnilo/prism-providers` family as `/<adapter>` subpaths (Azure/Bedrock/Vertex stop being special all-only manifests); independent publication continues inside `^0.3.0` ranges (which satisfy 0.3.1, 0.3.2, and 0.3.3). This page describes how they are packed, what each tarball contains, how to install them, the required non-optional **caret** `@arnilo/prism@^0.5.6` peer range, the release workflow, and the offline test budget. The measurable 1.0 readiness gates (command-per-gate) live in [`0.1.0-readiness.md`](history/./0.1.0-readiness.md).
|
|
9
9
|
|
|
10
10
|
Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package has a required `@arnilo/prism` peer inside the Decision B window — the caret current spec is `@arnilo/prism@^0.3.3` and every declared window peer satisfies it: packages republishing in the plan 050 cut carry `^0.3.2`; the plan 039 set keeps `^0.3.1`; unchanged packages keep their `^0.3.0` peer; profiles are pure manifests. The plan 050 republished set declares the required `@arnilo/prism@^0.3.2` peer; the plan 041-044 republished set keeps its existing `^0.3.0` window peer; unchanged packages keep their prior window. Installation activates no provider, listener, database, browser, credential, or tool capability.
|
|
11
11
|
|
|
@@ -14,16 +14,16 @@ Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package
|
|
|
14
14
|
|
|
15
15
|
| package | version | notes |
|
|
16
16
|
| --- | --- | --- |
|
|
17
|
-
| `@arnilo/prism` | 0.5.
|
|
18
|
-
| `@arnilo/prism-coding-tools` | 0.5.
|
|
19
|
-
| `@arnilo/prism-core` | 0.5.
|
|
20
|
-
| `@arnilo/prism-providers` | 0.5.
|
|
21
|
-
| `@arnilo/prism-acp-agent` | 0.5.
|
|
22
|
-
| `@arnilo/prism-ag-ui` | 0.5.
|
|
23
|
-
| `@arnilo/prism-mcp` | 0.5.
|
|
24
|
-
| `@arnilo/prism-memory` | 0.5.
|
|
25
|
-
| `@arnilo/prism-office` | 0.5.
|
|
26
|
-
| `@arnilo/prism-web-tools` | 0.5.
|
|
17
|
+
| `@arnilo/prism` | 0.5.6 | core — runtime, CLI/RPC, templates, docs |
|
|
18
|
+
| `@arnilo/prism-coding-tools` | 0.5.6 | family — /agent, /security, /document-reader, /openapi, /computer-use-linux, /dev, /caveman, /ponytail, /impeccable subpaths |
|
|
19
|
+
| `@arnilo/prism-core` | 0.5.6 | family — /runtime, /sessions, /governance, /credentials, /enterprise, /work, /validation subpaths |
|
|
20
|
+
| `@arnilo/prism-providers` | 0.5.6 | family — all provider adapters as `/<adapter>` subpaths |
|
|
21
|
+
| `@arnilo/prism-acp-agent` | 0.5.6 | capability — ACP adapter |
|
|
22
|
+
| `@arnilo/prism-ag-ui` | 0.5.6 | capability — AG-UI/A2A/A2UI adapter |
|
|
23
|
+
| `@arnilo/prism-mcp` | 0.5.6 | capability — MCP client/server/OAuth interop |
|
|
24
|
+
| `@arnilo/prism-memory` | 0.5.6 | capability — memory plus /rag, /compaction/*, /graft, /wiki subpaths |
|
|
25
|
+
| `@arnilo/prism-office` | 0.5.6 | capability — /documents, /sheets, /diagrams subpaths |
|
|
26
|
+
| `@arnilo/prism-web-tools` | 0.5.6 | capability — Brave/Exa/Firecrawl plus peer-gated /browser and /obscura subpaths |
|
|
27
27
|
<!-- generated:package-truth:inventory end -->
|
|
28
28
|
|
|
29
29
|
|
|
@@ -32,26 +32,26 @@ Core `@arnilo/prism` ships runtime, CLI, templates, and docs. Every code package
|
|
|
32
32
|
|
|
33
33
|
| adapter package | version |
|
|
34
34
|
| --- | --- |
|
|
35
|
-
| `@arnilo/prism-providers/ai-sdk` | 0.5.
|
|
36
|
-
| `@arnilo/prism-providers/alibaba` | 0.5.
|
|
37
|
-
| `@arnilo/prism-providers/anthropic` | 0.5.
|
|
38
|
-
| `@arnilo/prism-providers/azure` | 0.5.
|
|
39
|
-
| `@arnilo/prism-providers/bedrock` | 0.5.
|
|
40
|
-
| `@arnilo/prism-providers/clinepass` | 0.5.
|
|
41
|
-
| `@arnilo/prism-providers/commandcode` | 0.5.
|
|
42
|
-
| `@arnilo/prism-providers/deepseek` | 0.5.
|
|
43
|
-
| `@arnilo/prism-providers/google` | 0.5.
|
|
44
|
-
| `@arnilo/prism-providers/hyper` | 0.5.
|
|
45
|
-
| `@arnilo/prism-providers/kimi` | 0.5.
|
|
46
|
-
| `@arnilo/prism-providers/model-discovery` | 0.5.
|
|
47
|
-
| `@arnilo/prism-providers/neuralwatt` | 0.5.
|
|
48
|
-
| `@arnilo/prism-providers/ollama` | 0.5.
|
|
49
|
-
| `@arnilo/prism-providers/openai` | 0.5.
|
|
50
|
-
| `@arnilo/prism-providers/opencode-go` | 0.5.
|
|
51
|
-
| `@arnilo/prism-providers/openrouter` | 0.5.
|
|
52
|
-
| `@arnilo/prism-providers/vertex` | 0.5.
|
|
53
|
-
| `@arnilo/prism-providers/xai` | 0.5.
|
|
54
|
-
| `@arnilo/prism-providers/zai` | 0.5.
|
|
35
|
+
| `@arnilo/prism-providers/ai-sdk` | 0.5.6 |
|
|
36
|
+
| `@arnilo/prism-providers/alibaba` | 0.5.6 |
|
|
37
|
+
| `@arnilo/prism-providers/anthropic` | 0.5.6 |
|
|
38
|
+
| `@arnilo/prism-providers/azure` | 0.5.6 |
|
|
39
|
+
| `@arnilo/prism-providers/bedrock` | 0.5.6 |
|
|
40
|
+
| `@arnilo/prism-providers/clinepass` | 0.5.6 |
|
|
41
|
+
| `@arnilo/prism-providers/commandcode` | 0.5.6 |
|
|
42
|
+
| `@arnilo/prism-providers/deepseek` | 0.5.6 |
|
|
43
|
+
| `@arnilo/prism-providers/google` | 0.5.6 |
|
|
44
|
+
| `@arnilo/prism-providers/hyper` | 0.5.6 |
|
|
45
|
+
| `@arnilo/prism-providers/kimi` | 0.5.6 |
|
|
46
|
+
| `@arnilo/prism-providers/model-discovery` | 0.5.6 |
|
|
47
|
+
| `@arnilo/prism-providers/neuralwatt` | 0.5.6 |
|
|
48
|
+
| `@arnilo/prism-providers/ollama` | 0.5.6 |
|
|
49
|
+
| `@arnilo/prism-providers/openai` | 0.5.6 |
|
|
50
|
+
| `@arnilo/prism-providers/opencode-go` | 0.5.6 |
|
|
51
|
+
| `@arnilo/prism-providers/openrouter` | 0.5.6 |
|
|
52
|
+
| `@arnilo/prism-providers/vertex` | 0.5.6 |
|
|
53
|
+
| `@arnilo/prism-providers/xai` | 0.5.6 |
|
|
54
|
+
| `@arnilo/prism-providers/zai` | 0.5.6 |
|
|
55
55
|
<!-- generated:package-truth:providers end -->
|
|
56
56
|
|
|
57
57
|
|
|
@@ -143,7 +143,7 @@ A packed tarball contains only public compiled output and release files:
|
|
|
143
143
|
- Code packages ship `README.md`, `LICENSE`, and `CHANGELOG.md`; family/profile packages ship `README.md` and `CHANGELOG.md`.
|
|
144
144
|
- The core tarball additionally ships the full `docs/` directory (the docs hub), `templates/init/`, and the `templates/` gallery (e.g. `deep-research`) used by `prism init`.
|
|
145
145
|
- `dist/cli.js` and the `bin` link in core.
|
|
146
|
-
- **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.5.
|
|
146
|
+
- **Tarball filenames.** npm strips the `@scope/` prefix, so the core package `@arnilo/prism` produces a tarball named `arnilo-prism-0.5.6.tgz`; family packages produce `arnilo-prism-core-0.5.6.tgz`, `arnilo-prism-coding-tools-0.5.6.tgz`, `arnilo-prism-providers-0.5.6.tgz` (all 19 adapters inside), `arnilo-prism-memory-0.5.6.tgz`, `arnilo-prism-web-tools-0.5.6.tgz`, and `arnilo-prism-office-0.5.6.tgz`; capability packages like `arnilo-prism-mcp-0.5.6.tgz` carry their own package version. Independent-package tags carry their own version. The CLI bin name `prism` is unaffected by the package name (`npx prism` still works; npm allows the bin field to differ from the package name).
|
|
147
147
|
|
|
148
148
|
Excluded from every tarball by `files` negation:
|
|
149
149
|
|
package/docs/wiki.md
CHANGED
|
@@ -17,7 +17,7 @@ It integrates Tobias Lütke's [`qmd`](https://github.com/tobi/qmd) on-device hyb
|
|
|
17
17
|
|
|
18
18
|
The Karpathy LLM Wiki pattern is structured into 3 distinct tiers:
|
|
19
19
|
|
|
20
|
-
1. **Raw Sources (Immutable)**: Source code files, design docs, transcripts, journals, and Markdown notes. Raw sources are strictly read-only and never mutated.
|
|
20
|
+
1. **Raw Sources (Immutable)**: Source code files, design docs, transcripts, journals, and Markdown notes. Raw sources are strictly read-only and never mutated. New external material arrives through the ingest staging area (`raw/ingest/<utc>-<slug>/`): an immutable `source.*` original plus a UTF-8 `extract.md` the maintainer skill files into the wiki.
|
|
21
21
|
2. **Compiled Wiki (`.wiki/`)**: Persistent, cross-linked Markdown documents containing synthesized architecture models, entity descriptions, decision records, and line-anchored claims.
|
|
22
22
|
3. **Schema & Protocols (`SCHEMA.md`)**: Operational guidelines governing OKF v0.2 emission, entity categorization, citation rules (`file:///path#Lxx-Lyy`), catalog indexing (`index.md`), and chronological change logging (`log.md`).
|
|
23
23
|
|
|
@@ -39,12 +39,14 @@ The Karpathy LLM Wiki pattern is structured into 3 distinct tiers:
|
|
|
39
39
|
- `wiki_search`: `{ query: string, mode?: "search" | "vsearch" | "query", maxResults?: number }`
|
|
40
40
|
- `wiki_read_page`: `{ pagePath: string }` — `pagePath` must resolve inside the wiki root (lexical + `fs.realpath` containment). Traversal (sibling-prefix, `..`, absolute paths) and symlinks pointing outside the wiki throw an access-denied error; a missing contained page returns `found: false`.
|
|
41
41
|
- `wiki_record_insight`: `{ title: string, content: string, category?: "decision" | "concept" | "entity" }` — title and content must be non-empty; titles are capped at 200 characters, content at 65,536 bytes, and control characters/newlines in titles are collapsed to spaces so titles cannot inject Markdown headings, index entries, or log entries.
|
|
42
|
+
- `wiki_ingest`: `{ text?: string, path?: string, url?: string, title?: string }` — stages one raw source and returns a filing brief for the `wiki-maintainer` skill (see `/wiki-ingest` below). Exactly one of `text`/`path`/`url` must be provided; `url` requires a host `fetchUrl` hook.
|
|
42
43
|
|
|
43
44
|
### Slash Commands
|
|
44
45
|
|
|
45
46
|
- `/wiki-init`: Scaffolds `.wiki/`, instantiates `SCHEMA.md`, `index.md`, and `log.md`, deploys skills, and adds the `qmd` collection.
|
|
46
47
|
- `/wiki-refresh`: Detects modified source files via SHA-256 Merkle diffing, compiles updates to affected entity pages, reconciles contradictions in `log.md`, and runs `qmd update`.
|
|
47
48
|
- `/wiki-lint`: Checks OKF frontmatter (`type`, ISO `generated.at`), leftover `[[wikilinks]]`, unresolved relative markdown links, dead line anchors, and orphan pages.
|
|
49
|
+
- `/wiki-ingest`: `{ text?, path?, url?, title? }` — stages one external source into `raw/ingest/<utc>-<slug>/` (`source.*` original + `extract.md`), then returns a brief (staged paths, extract preview, source URL when applicable, Karpathy filing checklist). When the host injects `drivers`, the command calls `drivers.startRun(brief, { activeSkills: ["wiki-maintainer"] })` so the maintainer skill files the source into the wiki; without drivers it stages only and reports `runStarted: false`. Results are labeled `metadata.trust: "untrusted_external"`.
|
|
48
50
|
|
|
49
51
|
### Standalone CLI Commands
|
|
50
52
|
|
|
@@ -60,12 +62,49 @@ npx prism-wiki lint
|
|
|
60
62
|
|
|
61
63
|
# Search wiki from terminal
|
|
62
64
|
npx prism-wiki search "How does authentication work?" --mode query
|
|
65
|
+
|
|
66
|
+
# Stage an external source for the wiki
|
|
67
|
+
npx prism-wiki ingest --path notes/paper.pdf --title "Paper"
|
|
68
|
+
|
|
69
|
+
# `--url` is a usage error in the standalone CLI:
|
|
70
|
+
# the wiki package never fetches — URL ingest needs a host fetchUrl hook
|
|
71
|
+
npx prism-wiki ingest --url https://example.com/rfc.pdf # → exit 1
|
|
63
72
|
```
|
|
64
73
|
|
|
65
74
|
## Outputs / response / events
|
|
66
75
|
|
|
67
76
|
- `wiki_search` returns a structured markdown payload containing section breadcrumbs, conceptual summaries, and clickable source line links (`file:///path#Lxx-Lyy`).
|
|
68
77
|
- Lifecycle commands return status objects (`{ status: "initialized" | "refreshed" | "clean", ok: boolean }`).
|
|
78
|
+
- `wiki_ingest` / `/wiki-ingest` return the staged paths, the (capped) extract preview, and a filing brief; `value.runStarted` reports whether a driver run was started.
|
|
79
|
+
|
|
80
|
+
### `ingestWikiSource(input, options)`
|
|
81
|
+
|
|
82
|
+
The staging primitive behind `/wiki-ingest`, `wiki_ingest`, and the CLI. Accepts `{ text?, path?, bytes?, url?, filename?, title? }` (precedence `path` > `bytes` > `url` > `text`) and returns `{ id, rawDir, sourcePath, extractPath, mediaType?, extract, truncated, url? }` (`url` present only for URL-staged sources).
|
|
83
|
+
|
|
84
|
+
| Input | Parse behavior |
|
|
85
|
+
| :--- | :--- |
|
|
86
|
+
| Text-like files and `text` | Decoded as UTF-8 (RAG text/markdown/html parsers) |
|
|
87
|
+
| Uncompressed PDF | Parsed by the RAG PDF parser (bounded pages/bytes) |
|
|
88
|
+
| Compressed PDF / DOCX | Throws a named error unless the host supplies `options.extractDocument` (e.g. wire `createDocumentReader()` from `@arnilo/prism-coding-tools/document-reader`) |
|
|
89
|
+
| `url` | `assertSsrfAllowedUrl` runs first (private/link-local hosts rejected before any fetch); then the host `fetchUrl` hook supplies the bytes/text — missing or empty hook output fails closed. Staged filename comes from the hook, the URL extension (`doc.pdf`), or `source.md` |
|
|
90
|
+
| Images | Staged as-is; stub extract points at the staged `source.*` — no OCR; view the file |
|
|
91
|
+
| Unknown binary | Fails closed unless `extractDocument` claims it |
|
|
92
|
+
|
|
93
|
+
Caps: 32 MiB per staged input, 2 MiB per extract. `path` must resolve inside the workspace root (realpath containment). `log.md` gains an `**Ingested**` entry only when the wiki root exists.
|
|
94
|
+
|
|
95
|
+
Wiring a `fetchUrl` hook (the wiki package ships no HTTP client — hosts bring their own, e.g. Obscura):
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { runObscuraCli, validateObscuraWebUrl } from "@arnilo/prism-web-tools/obscura";
|
|
99
|
+
|
|
100
|
+
const wiki = createWikiExtension({
|
|
101
|
+
fetchUrl: async ({ url }) => {
|
|
102
|
+
validateObscuraWebUrl(url); // host-side SSRF gate of its own
|
|
103
|
+
const run = await runObscuraCli({ command: "obscura", args: ["fetch", url, "--dump", "markdown"] });
|
|
104
|
+
return { text: run.stdout, filename: "source.md" };
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
```
|
|
69
108
|
|
|
70
109
|
## Request/response example
|
|
71
110
|
|
|
@@ -135,12 +174,17 @@ Emitted `.wiki/` trees are [OKF v0.2](https://github.com/GoogleCloudPlatform/ope
|
|
|
135
174
|
|
|
136
175
|
## Extension and configuration notes
|
|
137
176
|
|
|
138
|
-
- The wiki subpath registers tools (`wiki_search`, `wiki_read_page`, `wiki_record_insight`), commands (`wiki-init`, `wiki-refresh`, `wiki-lint`), skills (`wiki-maintainer`, `wiki-searcher`), and instruction injectors (`wiki-guidance`) into Prism registries.
|
|
177
|
+
- The wiki subpath registers tools (`wiki_search`, `wiki_read_page`, `wiki_record_insight`, `wiki_ingest`), commands (`wiki-init`, `wiki-refresh`, `wiki-lint`, `wiki-ingest`), skills (`wiki-maintainer`, `wiki-searcher`), and instruction injectors (`wiki-guidance`) into Prism registries.
|
|
139
178
|
- It operates with zero core modifications and can be used with any `@arnilo/prism` agent.
|
|
140
179
|
- `qmd` is optional but recommended. When `@tobilu/qmd` is not installed, the search engine falls back to catalog matching against `index.md`.
|
|
141
180
|
|
|
181
|
+
## Ingest filing rules (Karpathy/OKF)
|
|
182
|
+
|
|
183
|
+
After staging, the `wiki-maintainer` skill files the source: read `.wiki/SCHEMA.md` and `index.md` first, read the staged `extract.md` (and view `source.*` for images/PDFs), integrate claims into existing entity/concept/decision pages — create pages only for genuinely new concepts — then emit OKF v0.2 frontmatter (`type` required; `sources[].resource` pointing at the staged `source.*` — for URL-staged sources the original URL is also legitimate; `generated.by: prism-wiki/ingest`), add per-claim footnotes keyed to `sources[].id` for source-specific claims, update `index.md`, and prepend an `**Ingested**` entry to `log.md`. Never copy raw bodies into wiki pages; one source per ingest; contradictions update the existing page and are logged. The same rules ship in every scaffolded `SCHEMA.md` (`## Ingest Protocol`).
|
|
184
|
+
|
|
142
185
|
## Security and performance notes
|
|
143
186
|
|
|
187
|
+
- **Ingest boundaries**: the wiki package never fetches — `url` inputs require a host `fetchUrl` hook, and `assertSsrfAllowedUrl` rejects private/link-local hosts before the hook runs; the standalone CLI rejects `--url` with a usage error. `path` inputs are contained inside the workspace root via realpath; extracts are untrusted data (`trust: "untrusted_external"`), never instructions; the raw layer stays read-only for the LLM; images get a stub extract (no OCR).
|
|
144
188
|
- **Source Immutability**: Raw source files are read-only and never modified by wiki operations.
|
|
145
189
|
- **Subprocess Safety**: All `qmd` subprocess calls use argument arrays (`execFile`) to prevent shell injection.
|
|
146
190
|
- **Path Containment**: Wiki and raw source paths are confined to the workspace root; directory traversal (`../`) is rejected.
|