Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions skills/objectstack-platform/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -174,14 +174,14 @@ export default defineStack({
### Full Configuration Reference

`defineStack()` accepts an `ObjectStackDefinitionInput`. Each top-level key
holds a collection of one metadata kind — `manifest`, `objects`,
`objectExtensions`, `views`, `apps`, `pages`, `dashboards`,
`reports`, `datasets`, `actions`, `flows`, `jobs`,
`emailTemplates`, `docs`, `books`, `positions`, `permissions`,
`capabilities`, `sharingRules`, `apis`, `webhooks`, `api`, `agents`,
`tools`, `skills`, `hooks`, `functions`, `mappings`, `analyticsCubes`,
`connectors`, `data` (seed), `datasources`, `datasourceMapping`,
`translations`, `i18n`, `plugins`, `devPlugins`, `requires`, `tiers`.
holds one metadata kind — `manifest`, `objects`, `objectExtensions`,
`views`, `apps`, `pages`, `dashboards`, `reports`, `datasets`,
`actions`, `flows`, `jobs`, `emailTemplates`, `docs`, `books`,
`positions`, `permissions`, `capabilities`, `sharingRules`, `apis`,
`webhooks`, `api`, `server`, `agents`, `tools`, `skills`, `hooks`,
`functions`, `mappings`, `analyticsCubes`, `connectors`, `data` (seed),
`datasources`, `datasourceMapping`, `translations`, `i18n`, `plugins`,
`devPlugins`, `requires`, `tiers`.

There is deliberately **no** top-level `workflows` or `approvals` collection:
an approval is authored as a flow with Approval nodes (ADR-0019), and record
Expand DownExpand Up@@ -315,7 +315,7 @@ manifest: {
}
```

**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is deprecated and ignored by the runtime.
**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is retired (ADR-0129 D3) and refused at load.

**`manifest.namespace` (ADR-0048):** Optional, but **enforced once set**. When a package declares `manifest.namespace: 'crm'`, every `object.name` must start with `crm_` or `defineStack` errors (`validateNamespacePrefix` in `@objectstack/spec`); the legacy `<ns>__<short>` double-underscore form is rejected, and `sys_`-prefixed names are platform-reserved and exempt. The namespace is also a package-ownership key — installing two packages that both claim `crm` fails with `NamespaceConflictError` (downgrade to a warning with `OS_METADATA_COLLISION=warn`). `os lint` additionally emits a non-fatal `naming/namespace-prefix` warning for bare-named UI/automation items (app, page, dashboard, flow, action, report, dataset) when a namespace is set.

Expand DownExpand Up@@ -576,7 +576,7 @@ PORT=8080 os start # production — pin the port explicitly (see Ports & netwo

A minimal but complete project from scratch:

**`package.json`** (mirrors the `blank` template):
**`package.json`**:
```json
{
"name": "my-todo-app",
Expand All@@ -588,13 +588,13 @@ A minimal but complete project from scratch:
"validate": "objectstack validate"
},
"dependencies": {
"@objectstack/spec": "^16.0.0-rc.1",
"@objectstack/runtime": "^16.0.0-rc.1",
"@objectstack/driver-memory": "^16.0.0-rc.1",
"@objectstack/plugin-hono-server": "^16.0.0-rc.1"
"@objectstack/spec": "^17.0.0",
"@objectstack/runtime": "^17.0.0",
"@objectstack/driver-memory": "^17.0.0",
"@objectstack/plugin-hono-server": "^17.0.0"
},
"devDependencies": {
"@objectstack/cli": "^16.0.0-rc.1",
"@objectstack/cli": "^17.0.0",
"typescript": "^6.0.0"
}
}
Expand DownExpand Up@@ -741,7 +741,7 @@ import { ObjectKernel } from '@objectstack/core';

const kernel = new ObjectKernel({
logger: {
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
level: 'info', // debug|info|warn|error|fatal|silent
format: 'json', // 'json' | 'text' | 'pretty'
},
defaultStartupTimeout: 30000, // Per plugin (ms)
Expand DownExpand Up@@ -772,7 +772,7 @@ import type { Plugin, PluginContext } from '@objectstack/core';
export interface Plugin {
name: string; // Unique identifier (reverse domain recommended)
version?: string; // Semantic version
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql
dependencies?: string[]; // Plugins that must init before this one

// Phase 1: Register services
Expand Down
2 changes: 1 addition & 1 deletion skills/objectstack-platform/rules/plugin-lifecycle.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ export interface Plugin {
version?: string;

/** Plugin type */
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app' | 'theme' | 'agent'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql

/** Plugins that must init before this one */
dependencies?: string[];
Expand Down
12 changes: 6 additions & 6 deletions skills/objectstack-platform/rules/service-registry.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -158,34 +158,34 @@ The REST plugin (`com.objectstack.rest.api`, `@objectstack/rest`) registers

## Core Fallback Injection

ObjectKernel auto-injects in-memory fallbacks for `core`-criticality services not registered by any plugin during Phase 1.
ObjectKernel auto-injects an in-memory fallback for each `core` service that has one and no plugin registered in Phase 1.

```
Phase 1: init() completes for all plugins
Kernel checks ServiceRequirementDef (@objectstack/spec/system):
'data' → required → ERROR if missing (no fallback; ObjectQLPlugin registers it)
'data' → required → ERROR if missing (ObjectQLPlugin registers it)
'metadata' → core → auto-inject createMemoryMetadata() if missing
'cache' → core → auto-inject createMemoryCache() if missing
'queue' → core → auto-inject createMemoryQueue() if missing
'job' → core → auto-inject createMemoryJob() if missing
'job' → core → NO fallback — warns; getService throws if missing
'i18n' → core → auto-inject createMemoryI18n() if missing
'auth' → core → no fallback factory — degraded-capability warning if missing
'auth' → core → NO fallback — warns; getService throws if missing
'realtime' → optional → skip, plugins should check availability
Phase 2: start() begins — all core services available
```

The fallbacks are **factories** exported from `@objectstack/core`
(`createMemoryCache`, `createMemoryMetadata`, `createMemoryQueue`,
`createMemoryJob`, `createMemoryI18n`) — not classes.
`createMemoryI18n`) — not classes; `job`/`auth` have none.

### Service Criticality Levels

| Level | Behavior |
|:------|:---------|
| `required` | Kernel throws if missing — system cannot start |
| `core` | Auto-injected in-memory fallback if no plugin provides it |
| `core` | In-memory fallback auto-injected where one exists, else warn |
| `optional` | Silently skipped — plugins must check before use |

## Incorrect vs Correct
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
docs(skills): objectstack-platform factual sweep — 6 false behavioral claims corrected by huangyiirene · Pull Request #13760 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions skills/objectstack-platform/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -174,14 +174,14 @@ export default defineStack({
### Full Configuration Reference

`defineStack()` accepts an `ObjectStackDefinitionInput`. Each top-level key
holds a collection of one metadata kind — `manifest`, `objects`,
`objectExtensions`, `views`, `apps`, `pages`, `dashboards`,
`reports`, `datasets`, `actions`, `flows`, `jobs`,
`emailTemplates`, `docs`, `books`, `positions`, `permissions`,
`capabilities`, `sharingRules`, `apis`, `webhooks`, `api`, `agents`,
`tools`, `skills`, `hooks`, `functions`, `mappings`, `analyticsCubes`,
`connectors`, `data` (seed), `datasources`, `datasourceMapping`,
`translations`, `i18n`, `plugins`, `devPlugins`, `requires`, `tiers`.
holds one metadata kind — `manifest`, `objects`, `objectExtensions`,
`views`, `apps`, `pages`, `dashboards`, `reports`, `datasets`,
`actions`, `flows`, `jobs`, `emailTemplates`, `docs`, `books`,
`positions`, `permissions`, `capabilities`, `sharingRules`, `apis`,
`webhooks`, `api`, `server`, `agents`, `tools`, `skills`, `hooks`,
`functions`, `mappings`, `analyticsCubes`, `connectors`, `data` (seed),
`datasources`, `datasourceMapping`, `translations`, `i18n`, `plugins`,
`devPlugins`, `requires`, `tiers`.

There is deliberately **no** top-level `workflows` or `approvals` collection:
an approval is authored as a flow with Approval nodes (ADR-0019), and record
Expand DownExpand Up@@ -315,7 +315,7 @@ manifest: {
}
```

**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is deprecated and ignored by the runtime.
**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is retired (ADR-0129 D3) and refused at load.

**`manifest.namespace` (ADR-0048):** Optional, but **enforced once set**. When a package declares `manifest.namespace: 'crm'`, every `object.name` must start with `crm_` or `defineStack` errors (`validateNamespacePrefix` in `@objectstack/spec`); the legacy `<ns>__<short>` double-underscore form is rejected, and `sys_`-prefixed names are platform-reserved and exempt. The namespace is also a package-ownership key — installing two packages that both claim `crm` fails with `NamespaceConflictError` (downgrade to a warning with `OS_METADATA_COLLISION=warn`). `os lint` additionally emits a non-fatal `naming/namespace-prefix` warning for bare-named UI/automation items (app, page, dashboard, flow, action, report, dataset) when a namespace is set.

Expand DownExpand Up@@ -576,7 +576,7 @@ PORT=8080 os start # production — pin the port explicitly (see Ports & netwo

A minimal but complete project from scratch:

**`package.json`** (mirrors the `blank` template):
**`package.json`**:
```json
{
"name": "my-todo-app",
Expand All@@ -588,13 +588,13 @@ A minimal but complete project from scratch:
"validate": "objectstack validate"
},
"dependencies": {
"@objectstack/spec": "^16.0.0-rc.1",
"@objectstack/runtime": "^16.0.0-rc.1",
"@objectstack/driver-memory": "^16.0.0-rc.1",
"@objectstack/plugin-hono-server": "^16.0.0-rc.1"
"@objectstack/spec": "^17.0.0",
"@objectstack/runtime": "^17.0.0",
"@objectstack/driver-memory": "^17.0.0",
"@objectstack/plugin-hono-server": "^17.0.0"
},
"devDependencies": {
"@objectstack/cli": "^16.0.0-rc.1",
"@objectstack/cli": "^17.0.0",
"typescript": "^6.0.0"
}
}
Expand DownExpand Up@@ -741,7 +741,7 @@ import { ObjectKernel } from '@objectstack/core';

const kernel = new ObjectKernel({
logger: {
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
level: 'info', // debug|info|warn|error|fatal|silent
format: 'json', // 'json' | 'text' | 'pretty'
},
defaultStartupTimeout: 30000, // Per plugin (ms)
Expand DownExpand Up@@ -772,7 +772,7 @@ import type { Plugin, PluginContext } from '@objectstack/core';
export interface Plugin {
name: string; // Unique identifier (reverse domain recommended)
version?: string; // Semantic version
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql
dependencies?: string[]; // Plugins that must init before this one

// Phase 1: Register services
Expand Down
2 changes: 1 addition & 1 deletion skills/objectstack-platform/rules/plugin-lifecycle.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ export interface Plugin {
version?: string;

/** Plugin type */
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app' | 'theme' | 'agent'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql

/** Plugins that must init before this one */
dependencies?: string[];
Expand Down
12 changes: 6 additions & 6 deletions skills/objectstack-platform/rules/service-registry.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -158,34 +158,34 @@ The REST plugin (`com.objectstack.rest.api`, `@objectstack/rest`) registers

## Core Fallback Injection

ObjectKernel auto-injects in-memory fallbacks for `core`-criticality services not registered by any plugin during Phase 1.
ObjectKernel auto-injects an in-memory fallback for each `core` service that has one and no plugin registered in Phase 1.

```
Phase 1: init() completes for all plugins
Kernel checks ServiceRequirementDef (@objectstack/spec/system):
'data' → required → ERROR if missing (no fallback; ObjectQLPlugin registers it)
'data' → required → ERROR if missing (ObjectQLPlugin registers it)
'metadata' → core → auto-inject createMemoryMetadata() if missing
'cache' → core → auto-inject createMemoryCache() if missing
'queue' → core → auto-inject createMemoryQueue() if missing
'job' → core → auto-inject createMemoryJob() if missing
'job' → core → NO fallback — warns; getService throws if missing
'i18n' → core → auto-inject createMemoryI18n() if missing
'auth' → core → no fallback factory — degraded-capability warning if missing
'auth' → core → NO fallback — warns; getService throws if missing
'realtime' → optional → skip, plugins should check availability
Phase 2: start() begins — all core services available
```

The fallbacks are **factories** exported from `@objectstack/core`
(`createMemoryCache`, `createMemoryMetadata`, `createMemoryQueue`,
`createMemoryJob`, `createMemoryI18n`) — not classes.
`createMemoryI18n`) — not classes; `job`/`auth` have none.

### Service Criticality Levels

| Level | Behavior |
|:------|:---------|
| `required` | Kernel throws if missing — system cannot start |
| `core` | Auto-injected in-memory fallback if no plugin provides it |
| `core` | In-memory fallback auto-injected where one exists, else warn |
| `optional` | Silently skipped — plugins must check before use |

## Incorrect vs Correct
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(skills): objectstack-platform factual sweep — 6 false behavioral claims corrected by huangyiirene · Pull Request #13760 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions skills/objectstack-platform/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -174,14 +174,14 @@ export default defineStack({
### Full Configuration Reference

`defineStack()` accepts an `ObjectStackDefinitionInput`. Each top-level key
holds a collection of one metadata kind — `manifest`, `objects`,
`objectExtensions`, `views`, `apps`, `pages`, `dashboards`,
`reports`, `datasets`, `actions`, `flows`, `jobs`,
`emailTemplates`, `docs`, `books`, `positions`, `permissions`,
`capabilities`, `sharingRules`, `apis`, `webhooks`, `api`, `agents`,
`tools`, `skills`, `hooks`, `functions`, `mappings`, `analyticsCubes`,
`connectors`, `data` (seed), `datasources`, `datasourceMapping`,
`translations`, `i18n`, `plugins`, `devPlugins`, `requires`, `tiers`.
holds one metadata kind — `manifest`, `objects`, `objectExtensions`,
`views`, `apps`, `pages`, `dashboards`, `reports`, `datasets`,
`actions`, `flows`, `jobs`, `emailTemplates`, `docs`, `books`,
`positions`, `permissions`, `capabilities`, `sharingRules`, `apis`,
`webhooks`, `api`, `server`, `agents`, `tools`, `skills`, `hooks`,
`functions`, `mappings`, `analyticsCubes`, `connectors`, `data` (seed),
`datasources`, `datasourceMapping`, `translations`, `i18n`, `plugins`,
`devPlugins`, `requires`, `tiers`.

There is deliberately **no** top-level `workflows` or `approvals` collection:
an approval is authored as a flow with Approval nodes (ADR-0019), and record
Expand DownExpand Up@@ -315,7 +315,7 @@ manifest: {
}
```

**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is deprecated and ignored by the runtime.
**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is retired (ADR-0129 D3) and refused at load.

**`manifest.namespace` (ADR-0048):** Optional, but **enforced once set**. When a package declares `manifest.namespace: 'crm'`, every `object.name` must start with `crm_` or `defineStack` errors (`validateNamespacePrefix` in `@objectstack/spec`); the legacy `<ns>__<short>` double-underscore form is rejected, and `sys_`-prefixed names are platform-reserved and exempt. The namespace is also a package-ownership key — installing two packages that both claim `crm` fails with `NamespaceConflictError` (downgrade to a warning with `OS_METADATA_COLLISION=warn`). `os lint` additionally emits a non-fatal `naming/namespace-prefix` warning for bare-named UI/automation items (app, page, dashboard, flow, action, report, dataset) when a namespace is set.

Expand DownExpand Up@@ -576,7 +576,7 @@ PORT=8080 os start # production — pin the port explicitly (see Ports & netwo

A minimal but complete project from scratch:

**`package.json`** (mirrors the `blank` template):
**`package.json`**:
```json
{
"name": "my-todo-app",
Expand All@@ -588,13 +588,13 @@ A minimal but complete project from scratch:
"validate": "objectstack validate"
},
"dependencies": {
"@objectstack/spec": "^16.0.0-rc.1",
"@objectstack/runtime": "^16.0.0-rc.1",
"@objectstack/driver-memory": "^16.0.0-rc.1",
"@objectstack/plugin-hono-server": "^16.0.0-rc.1"
"@objectstack/spec": "^17.0.0",
"@objectstack/runtime": "^17.0.0",
"@objectstack/driver-memory": "^17.0.0",
"@objectstack/plugin-hono-server": "^17.0.0"
},
"devDependencies": {
"@objectstack/cli": "^16.0.0-rc.1",
"@objectstack/cli": "^17.0.0",
"typescript": "^6.0.0"
}
}
Expand DownExpand Up@@ -741,7 +741,7 @@ import { ObjectKernel } from '@objectstack/core';

const kernel = new ObjectKernel({
logger: {
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
level: 'info', // debug|info|warn|error|fatal|silent
format: 'json', // 'json' | 'text' | 'pretty'
},
defaultStartupTimeout: 30000, // Per plugin (ms)
Expand DownExpand Up@@ -772,7 +772,7 @@ import type { Plugin, PluginContext } from '@objectstack/core';
export interface Plugin {
name: string; // Unique identifier (reverse domain recommended)
version?: string; // Semantic version
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql
dependencies?: string[]; // Plugins that must init before this one

// Phase 1: Register services
Expand Down
2 changes: 1 addition & 1 deletion skills/objectstack-platform/rules/plugin-lifecycle.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ export interface Plugin {
version?: string;

/** Plugin type */
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app' | 'theme' | 'agent'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql

/** Plugins that must init before this one */
dependencies?: string[];
Expand Down
12 changes: 6 additions & 6 deletions skills/objectstack-platform/rules/service-registry.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -158,34 +158,34 @@ The REST plugin (`com.objectstack.rest.api`, `@objectstack/rest`) registers

## Core Fallback Injection

ObjectKernel auto-injects in-memory fallbacks for `core`-criticality services not registered by any plugin during Phase 1.
ObjectKernel auto-injects an in-memory fallback for each `core` service that has one and no plugin registered in Phase 1.

```
Phase 1: init() completes for all plugins
Kernel checks ServiceRequirementDef (@objectstack/spec/system):
'data' → required → ERROR if missing (no fallback; ObjectQLPlugin registers it)
'data' → required → ERROR if missing (ObjectQLPlugin registers it)
'metadata' → core → auto-inject createMemoryMetadata() if missing
'cache' → core → auto-inject createMemoryCache() if missing
'queue' → core → auto-inject createMemoryQueue() if missing
'job' → core → auto-inject createMemoryJob() if missing
'job' → core → NO fallback — warns; getService throws if missing
'i18n' → core → auto-inject createMemoryI18n() if missing
'auth' → core → no fallback factory — degraded-capability warning if missing
'auth' → core → NO fallback — warns; getService throws if missing
'realtime' → optional → skip, plugins should check availability
Phase 2: start() begins — all core services available
```

The fallbacks are **factories** exported from `@objectstack/core`
(`createMemoryCache`, `createMemoryMetadata`, `createMemoryQueue`,
`createMemoryJob`, `createMemoryI18n`) — not classes.
`createMemoryI18n`) — not classes; `job`/`auth` have none.

### Service Criticality Levels

| Level | Behavior |
|:------|:---------|
| `required` | Kernel throws if missing — system cannot start |
| `core` | Auto-injected in-memory fallback if no plugin provides it |
| `core` | In-memory fallback auto-injected where one exists, else warn |
| `optional` | Silently skipped — plugins must check before use |

## Incorrect vs Correct
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(skills): objectstack-platform factual sweep — 6 false behavioral claims corrected by huangyiirene · Pull Request #13760 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions skills/objectstack-platform/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -174,14 +174,14 @@ export default defineStack({
### Full Configuration Reference

`defineStack()` accepts an `ObjectStackDefinitionInput`. Each top-level key
holds a collection of one metadata kind — `manifest`, `objects`,
`objectExtensions`, `views`, `apps`, `pages`, `dashboards`,
`reports`, `datasets`, `actions`, `flows`, `jobs`,
`emailTemplates`, `docs`, `books`, `positions`, `permissions`,
`capabilities`, `sharingRules`, `apis`, `webhooks`, `api`, `agents`,
`tools`, `skills`, `hooks`, `functions`, `mappings`, `analyticsCubes`,
`connectors`, `data` (seed), `datasources`, `datasourceMapping`,
`translations`, `i18n`, `plugins`, `devPlugins`, `requires`, `tiers`.
holds one metadata kind — `manifest`, `objects`, `objectExtensions`,
`views`, `apps`, `pages`, `dashboards`, `reports`, `datasets`,
`actions`, `flows`, `jobs`, `emailTemplates`, `docs`, `books`,
`positions`, `permissions`, `capabilities`, `sharingRules`, `apis`,
`webhooks`, `api`, `server`, `agents`, `tools`, `skills`, `hooks`,
`functions`, `mappings`, `analyticsCubes`, `connectors`, `data` (seed),
`datasources`, `datasourceMapping`, `translations`, `i18n`, `plugins`,
`devPlugins`, `requires`, `tiers`.

There is deliberately **no** top-level `workflows` or `approvals` collection:
an approval is authored as a flow with Approval nodes (ADR-0019), and record
Expand DownExpand Up@@ -315,7 +315,7 @@ manifest: {
}
```

**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is deprecated and ignored by the runtime.
**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is retired (ADR-0129 D3) and refused at load.

**`manifest.namespace` (ADR-0048):** Optional, but **enforced once set**. When a package declares `manifest.namespace: 'crm'`, every `object.name` must start with `crm_` or `defineStack` errors (`validateNamespacePrefix` in `@objectstack/spec`); the legacy `<ns>__<short>` double-underscore form is rejected, and `sys_`-prefixed names are platform-reserved and exempt. The namespace is also a package-ownership key — installing two packages that both claim `crm` fails with `NamespaceConflictError` (downgrade to a warning with `OS_METADATA_COLLISION=warn`). `os lint` additionally emits a non-fatal `naming/namespace-prefix` warning for bare-named UI/automation items (app, page, dashboard, flow, action, report, dataset) when a namespace is set.

Expand DownExpand Up@@ -576,7 +576,7 @@ PORT=8080 os start # production — pin the port explicitly (see Ports & netwo

A minimal but complete project from scratch:

**`package.json`** (mirrors the `blank` template):
**`package.json`**:
```json
{
"name": "my-todo-app",
Expand All@@ -588,13 +588,13 @@ A minimal but complete project from scratch:
"validate": "objectstack validate"
},
"dependencies": {
"@objectstack/spec": "^16.0.0-rc.1",
"@objectstack/runtime": "^16.0.0-rc.1",
"@objectstack/driver-memory": "^16.0.0-rc.1",
"@objectstack/plugin-hono-server": "^16.0.0-rc.1"
"@objectstack/spec": "^17.0.0",
"@objectstack/runtime": "^17.0.0",
"@objectstack/driver-memory": "^17.0.0",
"@objectstack/plugin-hono-server": "^17.0.0"
},
"devDependencies": {
"@objectstack/cli": "^16.0.0-rc.1",
"@objectstack/cli": "^17.0.0",
"typescript": "^6.0.0"
}
}
Expand DownExpand Up@@ -741,7 +741,7 @@ import { ObjectKernel } from '@objectstack/core';

const kernel = new ObjectKernel({
logger: {
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
level: 'info', // debug|info|warn|error|fatal|silent
format: 'json', // 'json' | 'text' | 'pretty'
},
defaultStartupTimeout: 30000, // Per plugin (ms)
Expand DownExpand Up@@ -772,7 +772,7 @@ import type { Plugin, PluginContext } from '@objectstack/core';
export interface Plugin {
name: string; // Unique identifier (reverse domain recommended)
version?: string; // Semantic version
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql
dependencies?: string[]; // Plugins that must init before this one

// Phase 1: Register services
Expand Down
2 changes: 1 addition & 1 deletion skills/objectstack-platform/rules/plugin-lifecycle.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ export interface Plugin {
version?: string;

/** Plugin type */
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app' | 'theme' | 'agent'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql

/** Plugins that must init before this one */
dependencies?: string[];
Expand Down
12 changes: 6 additions & 6 deletions skills/objectstack-platform/rules/service-registry.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -158,34 +158,34 @@ The REST plugin (`com.objectstack.rest.api`, `@objectstack/rest`) registers

## Core Fallback Injection

ObjectKernel auto-injects in-memory fallbacks for `core`-criticality services not registered by any plugin during Phase 1.
ObjectKernel auto-injects an in-memory fallback for each `core` service that has one and no plugin registered in Phase 1.

```
Phase 1: init() completes for all plugins
Kernel checks ServiceRequirementDef (@objectstack/spec/system):
'data' → required → ERROR if missing (no fallback; ObjectQLPlugin registers it)
'data' → required → ERROR if missing (ObjectQLPlugin registers it)
'metadata' → core → auto-inject createMemoryMetadata() if missing
'cache' → core → auto-inject createMemoryCache() if missing
'queue' → core → auto-inject createMemoryQueue() if missing
'job' → core → auto-inject createMemoryJob() if missing
'job' → core → NO fallback — warns; getService throws if missing
'i18n' → core → auto-inject createMemoryI18n() if missing
'auth' → core → no fallback factory — degraded-capability warning if missing
'auth' → core → NO fallback — warns; getService throws if missing
'realtime' → optional → skip, plugins should check availability
Phase 2: start() begins — all core services available
```

The fallbacks are **factories** exported from `@objectstack/core`
(`createMemoryCache`, `createMemoryMetadata`, `createMemoryQueue`,
`createMemoryJob`, `createMemoryI18n`) — not classes.
`createMemoryI18n`) — not classes; `job`/`auth` have none.

### Service Criticality Levels

| Level | Behavior |
|:------|:---------|
| `required` | Kernel throws if missing — system cannot start |
| `core` | Auto-injected in-memory fallback if no plugin provides it |
| `core` | In-memory fallback auto-injected where one exists, else warn |
| `optional` | Silently skipped — plugins must check before use |

## Incorrect vs Correct
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' docs(skills): objectstack-platform factual sweep — 6 false behavioral claims corrected by huangyiirene · Pull Request #13760 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions skills/objectstack-platform/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -174,14 +174,14 @@ export default defineStack({
### Full Configuration Reference

`defineStack()` accepts an `ObjectStackDefinitionInput`. Each top-level key
holds a collection of one metadata kind — `manifest`, `objects`,
`objectExtensions`, `views`, `apps`, `pages`, `dashboards`,
`reports`, `datasets`, `actions`, `flows`, `jobs`,
`emailTemplates`, `docs`, `books`, `positions`, `permissions`,
`capabilities`, `sharingRules`, `apis`, `webhooks`, `api`, `agents`,
`tools`, `skills`, `hooks`, `functions`, `mappings`, `analyticsCubes`,
`connectors`, `data` (seed), `datasources`, `datasourceMapping`,
`translations`, `i18n`, `plugins`, `devPlugins`, `requires`, `tiers`.
holds one metadata kind — `manifest`, `objects`, `objectExtensions`,
`views`, `apps`, `pages`, `dashboards`, `reports`, `datasets`,
`actions`, `flows`, `jobs`, `emailTemplates`, `docs`, `books`,
`positions`, `permissions`, `capabilities`, `sharingRules`, `apis`,
`webhooks`, `api`, `server`, `agents`, `tools`, `skills`, `hooks`,
`functions`, `mappings`, `analyticsCubes`, `connectors`, `data` (seed),
`datasources`, `datasourceMapping`, `translations`, `i18n`, `plugins`,
`devPlugins`, `requires`, `tiers`.

There is deliberately **no** top-level `workflows` or `approvals` collection:
an approval is authored as a flow with Approval nodes (ADR-0019), and record
Expand DownExpand Up@@ -315,7 +315,7 @@ manifest: {
}
```

**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is deprecated and ignored by the runtime.
**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is retired (ADR-0129 D3) and refused at load.

**`manifest.namespace` (ADR-0048):** Optional, but **enforced once set**. When a package declares `manifest.namespace: 'crm'`, every `object.name` must start with `crm_` or `defineStack` errors (`validateNamespacePrefix` in `@objectstack/spec`); the legacy `<ns>__<short>` double-underscore form is rejected, and `sys_`-prefixed names are platform-reserved and exempt. The namespace is also a package-ownership key — installing two packages that both claim `crm` fails with `NamespaceConflictError` (downgrade to a warning with `OS_METADATA_COLLISION=warn`). `os lint` additionally emits a non-fatal `naming/namespace-prefix` warning for bare-named UI/automation items (app, page, dashboard, flow, action, report, dataset) when a namespace is set.

Expand DownExpand Up@@ -576,7 +576,7 @@ PORT=8080 os start # production — pin the port explicitly (see Ports & netwo

A minimal but complete project from scratch:

**`package.json`** (mirrors the `blank` template):
**`package.json`**:
```json
{
"name": "my-todo-app",
Expand All@@ -588,13 +588,13 @@ A minimal but complete project from scratch:
"validate": "objectstack validate"
},
"dependencies": {
"@objectstack/spec": "^16.0.0-rc.1",
"@objectstack/runtime": "^16.0.0-rc.1",
"@objectstack/driver-memory": "^16.0.0-rc.1",
"@objectstack/plugin-hono-server": "^16.0.0-rc.1"
"@objectstack/spec": "^17.0.0",
"@objectstack/runtime": "^17.0.0",
"@objectstack/driver-memory": "^17.0.0",
"@objectstack/plugin-hono-server": "^17.0.0"
},
"devDependencies": {
"@objectstack/cli": "^16.0.0-rc.1",
"@objectstack/cli": "^17.0.0",
"typescript": "^6.0.0"
}
}
Expand DownExpand Up@@ -741,7 +741,7 @@ import { ObjectKernel } from '@objectstack/core';

const kernel = new ObjectKernel({
logger: {
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
level: 'info', // debug|info|warn|error|fatal|silent
format: 'json', // 'json' | 'text' | 'pretty'
},
defaultStartupTimeout: 30000, // Per plugin (ms)
Expand DownExpand Up@@ -772,7 +772,7 @@ import type { Plugin, PluginContext } from '@objectstack/core';
export interface Plugin {
name: string; // Unique identifier (reverse domain recommended)
version?: string; // Semantic version
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql
dependencies?: string[]; // Plugins that must init before this one

// Phase 1: Register services
Expand Down
2 changes: 1 addition & 1 deletion skills/objectstack-platform/rules/plugin-lifecycle.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ export interface Plugin {
version?: string;

/** Plugin type */
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app' | 'theme' | 'agent'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql

/** Plugins that must init before this one */
dependencies?: string[];
Expand Down
12 changes: 6 additions & 6 deletions skills/objectstack-platform/rules/service-registry.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -158,34 +158,34 @@ The REST plugin (`com.objectstack.rest.api`, `@objectstack/rest`) registers

## Core Fallback Injection

ObjectKernel auto-injects in-memory fallbacks for `core`-criticality services not registered by any plugin during Phase 1.
ObjectKernel auto-injects an in-memory fallback for each `core` service that has one and no plugin registered in Phase 1.

```
Phase 1: init() completes for all plugins
Kernel checks ServiceRequirementDef (@objectstack/spec/system):
'data' → required → ERROR if missing (no fallback; ObjectQLPlugin registers it)
'data' → required → ERROR if missing (ObjectQLPlugin registers it)
'metadata' → core → auto-inject createMemoryMetadata() if missing
'cache' → core → auto-inject createMemoryCache() if missing
'queue' → core → auto-inject createMemoryQueue() if missing
'job' → core → auto-inject createMemoryJob() if missing
'job' → core → NO fallback — warns; getService throws if missing
'i18n' → core → auto-inject createMemoryI18n() if missing
'auth' → core → no fallback factory — degraded-capability warning if missing
'auth' → core → NO fallback — warns; getService throws if missing
'realtime' → optional → skip, plugins should check availability
Phase 2: start() begins — all core services available
```

The fallbacks are **factories** exported from `@objectstack/core`
(`createMemoryCache`, `createMemoryMetadata`, `createMemoryQueue`,
`createMemoryJob`, `createMemoryI18n`) — not classes.
`createMemoryI18n`) — not classes; `job`/`auth` have none.

### Service Criticality Levels

| Level | Behavior |
|:------|:---------|
| `required` | Kernel throws if missing — system cannot start |
| `core` | Auto-injected in-memory fallback if no plugin provides it |
| `core` | In-memory fallback auto-injected where one exists, else warn |
| `optional` | Silently skipped — plugins must check before use |

## Incorrect vs Correct
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(skills): objectstack-platform factual sweep — 6 false behavioral claims corrected by huangyiirene · Pull Request #13760 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions skills/objectstack-platform/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -174,14 +174,14 @@ export default defineStack({
### Full Configuration Reference

`defineStack()` accepts an `ObjectStackDefinitionInput`. Each top-level key
holds a collection of one metadata kind — `manifest`, `objects`,
`objectExtensions`, `views`, `apps`, `pages`, `dashboards`,
`reports`, `datasets`, `actions`, `flows`, `jobs`,
`emailTemplates`, `docs`, `books`, `positions`, `permissions`,
`capabilities`, `sharingRules`, `apis`, `webhooks`, `api`, `agents`,
`tools`, `skills`, `hooks`, `functions`, `mappings`, `analyticsCubes`,
`connectors`, `data` (seed), `datasources`, `datasourceMapping`,
`translations`, `i18n`, `plugins`, `devPlugins`, `requires`, `tiers`.
holds one metadata kind — `manifest`, `objects`, `objectExtensions`,
`views`, `apps`, `pages`, `dashboards`, `reports`, `datasets`,
`actions`, `flows`, `jobs`, `emailTemplates`, `docs`, `books`,
`positions`, `permissions`, `capabilities`, `sharingRules`, `apis`,
`webhooks`, `api`, `server`, `agents`, `tools`, `skills`, `hooks`,
`functions`, `mappings`, `analyticsCubes`, `connectors`, `data` (seed),
`datasources`, `datasourceMapping`, `translations`, `i18n`, `plugins`,
`devPlugins`, `requires`, `tiers`.

There is deliberately **no** top-level `workflows` or `approvals` collection:
an approval is authored as a flow with Approval nodes (ADR-0019), and record
Expand DownExpand Up@@ -315,7 +315,7 @@ manifest: {
}
```

**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is deprecated and ignored by the runtime.
**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is retired (ADR-0129 D3) and refused at load.

**`manifest.namespace` (ADR-0048):** Optional, but **enforced once set**. When a package declares `manifest.namespace: 'crm'`, every `object.name` must start with `crm_` or `defineStack` errors (`validateNamespacePrefix` in `@objectstack/spec`); the legacy `<ns>__<short>` double-underscore form is rejected, and `sys_`-prefixed names are platform-reserved and exempt. The namespace is also a package-ownership key — installing two packages that both claim `crm` fails with `NamespaceConflictError` (downgrade to a warning with `OS_METADATA_COLLISION=warn`). `os lint` additionally emits a non-fatal `naming/namespace-prefix` warning for bare-named UI/automation items (app, page, dashboard, flow, action, report, dataset) when a namespace is set.

Expand DownExpand Up@@ -576,7 +576,7 @@ PORT=8080 os start # production — pin the port explicitly (see Ports & netwo

A minimal but complete project from scratch:

**`package.json`** (mirrors the `blank` template):
**`package.json`**:
```json
{
"name": "my-todo-app",
Expand All@@ -588,13 +588,13 @@ A minimal but complete project from scratch:
"validate": "objectstack validate"
},
"dependencies": {
"@objectstack/spec": "^16.0.0-rc.1",
"@objectstack/runtime": "^16.0.0-rc.1",
"@objectstack/driver-memory": "^16.0.0-rc.1",
"@objectstack/plugin-hono-server": "^16.0.0-rc.1"
"@objectstack/spec": "^17.0.0",
"@objectstack/runtime": "^17.0.0",
"@objectstack/driver-memory": "^17.0.0",
"@objectstack/plugin-hono-server": "^17.0.0"
},
"devDependencies": {
"@objectstack/cli": "^16.0.0-rc.1",
"@objectstack/cli": "^17.0.0",
"typescript": "^6.0.0"
}
}
Expand DownExpand Up@@ -741,7 +741,7 @@ import { ObjectKernel } from '@objectstack/core';

const kernel = new ObjectKernel({
logger: {
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
level: 'info', // debug|info|warn|error|fatal|silent
format: 'json', // 'json' | 'text' | 'pretty'
},
defaultStartupTimeout: 30000, // Per plugin (ms)
Expand DownExpand Up@@ -772,7 +772,7 @@ import type { Plugin, PluginContext } from '@objectstack/core';
export interface Plugin {
name: string; // Unique identifier (reverse domain recommended)
version?: string; // Semantic version
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql
dependencies?: string[]; // Plugins that must init before this one

// Phase 1: Register services
Expand Down
2 changes: 1 addition & 1 deletion skills/objectstack-platform/rules/plugin-lifecycle.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ export interface Plugin {
version?: string;

/** Plugin type */
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app' | 'theme' | 'agent'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql

/** Plugins that must init before this one */
dependencies?: string[];
Expand Down
12 changes: 6 additions & 6 deletions skills/objectstack-platform/rules/service-registry.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -158,34 +158,34 @@ The REST plugin (`com.objectstack.rest.api`, `@objectstack/rest`) registers

## Core Fallback Injection

ObjectKernel auto-injects in-memory fallbacks for `core`-criticality services not registered by any plugin during Phase 1.
ObjectKernel auto-injects an in-memory fallback for each `core` service that has one and no plugin registered in Phase 1.

```
Phase 1: init() completes for all plugins
Kernel checks ServiceRequirementDef (@objectstack/spec/system):
'data' → required → ERROR if missing (no fallback; ObjectQLPlugin registers it)
'data' → required → ERROR if missing (ObjectQLPlugin registers it)
'metadata' → core → auto-inject createMemoryMetadata() if missing
'cache' → core → auto-inject createMemoryCache() if missing
'queue' → core → auto-inject createMemoryQueue() if missing
'job' → core → auto-inject createMemoryJob() if missing
'job' → core → NO fallback — warns; getService throws if missing
'i18n' → core → auto-inject createMemoryI18n() if missing
'auth' → core → no fallback factory — degraded-capability warning if missing
'auth' → core → NO fallback — warns; getService throws if missing
'realtime' → optional → skip, plugins should check availability
Phase 2: start() begins — all core services available
```

The fallbacks are **factories** exported from `@objectstack/core`
(`createMemoryCache`, `createMemoryMetadata`, `createMemoryQueue`,
`createMemoryJob`, `createMemoryI18n`) — not classes.
`createMemoryI18n`) — not classes; `job`/`auth` have none.

### Service Criticality Levels

| Level | Behavior |
|:------|:---------|
| `required` | Kernel throws if missing — system cannot start |
| `core` | Auto-injected in-memory fallback if no plugin provides it |
| `core` | In-memory fallback auto-injected where one exists, else warn |
| `optional` | Silently skipped — plugins must check before use |

## Incorrect vs Correct
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(skills): objectstack-platform factual sweep — 6 false behavioral claims corrected by huangyiirene · Pull Request #13760 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions skills/objectstack-platform/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -174,14 +174,14 @@ export default defineStack({
### Full Configuration Reference

`defineStack()` accepts an `ObjectStackDefinitionInput`. Each top-level key
holds a collection of one metadata kind — `manifest`, `objects`,
`objectExtensions`, `views`, `apps`, `pages`, `dashboards`,
`reports`, `datasets`, `actions`, `flows`, `jobs`,
`emailTemplates`, `docs`, `books`, `positions`, `permissions`,
`capabilities`, `sharingRules`, `apis`, `webhooks`, `api`, `agents`,
`tools`, `skills`, `hooks`, `functions`, `mappings`, `analyticsCubes`,
`connectors`, `data` (seed), `datasources`, `datasourceMapping`,
`translations`, `i18n`, `plugins`, `devPlugins`, `requires`, `tiers`.
holds one metadata kind — `manifest`, `objects`, `objectExtensions`,
`views`, `apps`, `pages`, `dashboards`, `reports`, `datasets`,
`actions`, `flows`, `jobs`, `emailTemplates`, `docs`, `books`,
`positions`, `permissions`, `capabilities`, `sharingRules`, `apis`,
`webhooks`, `api`, `server`, `agents`, `tools`, `skills`, `hooks`,
`functions`, `mappings`, `analyticsCubes`, `connectors`, `data` (seed),
`datasources`, `datasourceMapping`, `translations`, `i18n`, `plugins`,
`devPlugins`, `requires`, `tiers`.

There is deliberately **no** top-level `workflows` or `approvals` collection:
an approval is authored as a flow with Approval nodes (ADR-0019), and record
Expand DownExpand Up@@ -315,7 +315,7 @@ manifest: {
}
```

**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is deprecated and ignored by the runtime.
**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is retired (ADR-0129 D3) and refused at load.

**`manifest.namespace` (ADR-0048):** Optional, but **enforced once set**. When a package declares `manifest.namespace: 'crm'`, every `object.name` must start with `crm_` or `defineStack` errors (`validateNamespacePrefix` in `@objectstack/spec`); the legacy `<ns>__<short>` double-underscore form is rejected, and `sys_`-prefixed names are platform-reserved and exempt. The namespace is also a package-ownership key — installing two packages that both claim `crm` fails with `NamespaceConflictError` (downgrade to a warning with `OS_METADATA_COLLISION=warn`). `os lint` additionally emits a non-fatal `naming/namespace-prefix` warning for bare-named UI/automation items (app, page, dashboard, flow, action, report, dataset) when a namespace is set.

Expand DownExpand Up@@ -576,7 +576,7 @@ PORT=8080 os start # production — pin the port explicitly (see Ports & netwo

A minimal but complete project from scratch:

**`package.json`** (mirrors the `blank` template):
**`package.json`**:
```json
{
"name": "my-todo-app",
Expand All@@ -588,13 +588,13 @@ A minimal but complete project from scratch:
"validate": "objectstack validate"
},
"dependencies": {
"@objectstack/spec": "^16.0.0-rc.1",
"@objectstack/runtime": "^16.0.0-rc.1",
"@objectstack/driver-memory": "^16.0.0-rc.1",
"@objectstack/plugin-hono-server": "^16.0.0-rc.1"
"@objectstack/spec": "^17.0.0",
"@objectstack/runtime": "^17.0.0",
"@objectstack/driver-memory": "^17.0.0",
"@objectstack/plugin-hono-server": "^17.0.0"
},
"devDependencies": {
"@objectstack/cli": "^16.0.0-rc.1",
"@objectstack/cli": "^17.0.0",
"typescript": "^6.0.0"
}
}
Expand DownExpand Up@@ -741,7 +741,7 @@ import { ObjectKernel } from '@objectstack/core';

const kernel = new ObjectKernel({
logger: {
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
level: 'info', // debug|info|warn|error|fatal|silent
format: 'json', // 'json' | 'text' | 'pretty'
},
defaultStartupTimeout: 30000, // Per plugin (ms)
Expand DownExpand Up@@ -772,7 +772,7 @@ import type { Plugin, PluginContext } from '@objectstack/core';
export interface Plugin {
name: string; // Unique identifier (reverse domain recommended)
version?: string; // Semantic version
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql
dependencies?: string[]; // Plugins that must init before this one

// Phase 1: Register services
Expand Down
2 changes: 1 addition & 1 deletion skills/objectstack-platform/rules/plugin-lifecycle.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ export interface Plugin {
version?: string;

/** Plugin type */
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app' | 'theme' | 'agent'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql

/** Plugins that must init before this one */
dependencies?: string[];
Expand Down
12 changes: 6 additions & 6 deletions skills/objectstack-platform/rules/service-registry.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -158,34 +158,34 @@ The REST plugin (`com.objectstack.rest.api`, `@objectstack/rest`) registers

## Core Fallback Injection

ObjectKernel auto-injects in-memory fallbacks for `core`-criticality services not registered by any plugin during Phase 1.
ObjectKernel auto-injects an in-memory fallback for each `core` service that has one and no plugin registered in Phase 1.

```
Phase 1: init() completes for all plugins
Kernel checks ServiceRequirementDef (@objectstack/spec/system):
'data' → required → ERROR if missing (no fallback; ObjectQLPlugin registers it)
'data' → required → ERROR if missing (ObjectQLPlugin registers it)
'metadata' → core → auto-inject createMemoryMetadata() if missing
'cache' → core → auto-inject createMemoryCache() if missing
'queue' → core → auto-inject createMemoryQueue() if missing
'job' → core → auto-inject createMemoryJob() if missing
'job' → core → NO fallback — warns; getService throws if missing
'i18n' → core → auto-inject createMemoryI18n() if missing
'auth' → core → no fallback factory — degraded-capability warning if missing
'auth' → core → NO fallback — warns; getService throws if missing
'realtime' → optional → skip, plugins should check availability
Phase 2: start() begins — all core services available
```

The fallbacks are **factories** exported from `@objectstack/core`
(`createMemoryCache`, `createMemoryMetadata`, `createMemoryQueue`,
`createMemoryJob`, `createMemoryI18n`) — not classes.
`createMemoryI18n`) — not classes; `job`/`auth` have none.

### Service Criticality Levels

| Level | Behavior |
|:------|:---------|
| `required` | Kernel throws if missing — system cannot start |
| `core` | Auto-injected in-memory fallback if no plugin provides it |
| `core` | In-memory fallback auto-injected where one exists, else warn |
| `optional` | Silently skipped — plugins must check before use |

## Incorrect vs Correct
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); docs(skills): objectstack-platform factual sweep — 6 false behavioral claims corrected by huangyiirene · Pull Request #13760 · objectstack-ai/objectstack · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions skills/objectstack-platform/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -174,14 +174,14 @@ export default defineStack({
### Full Configuration Reference

`defineStack()` accepts an `ObjectStackDefinitionInput`. Each top-level key
holds a collection of one metadata kind — `manifest`, `objects`,
`objectExtensions`, `views`, `apps`, `pages`, `dashboards`,
`reports`, `datasets`, `actions`, `flows`, `jobs`,
`emailTemplates`, `docs`, `books`, `positions`, `permissions`,
`capabilities`, `sharingRules`, `apis`, `webhooks`, `api`, `agents`,
`tools`, `skills`, `hooks`, `functions`, `mappings`, `analyticsCubes`,
`connectors`, `data` (seed), `datasources`, `datasourceMapping`,
`translations`, `i18n`, `plugins`, `devPlugins`, `requires`, `tiers`.
holds one metadata kind — `manifest`, `objects`, `objectExtensions`,
`views`, `apps`, `pages`, `dashboards`, `reports`, `datasets`,
`actions`, `flows`, `jobs`, `emailTemplates`, `docs`, `books`,
`positions`, `permissions`, `capabilities`, `sharingRules`, `apis`,
`webhooks`, `api`, `server`, `agents`, `tools`, `skills`, `hooks`,
`functions`, `mappings`, `analyticsCubes`, `connectors`, `data` (seed),
`datasources`, `datasourceMapping`, `translations`, `i18n`, `plugins`,
`devPlugins`, `requires`, `tiers`.

There is deliberately **no** top-level `workflows` or `approvals` collection:
an approval is authored as a flow with Approval nodes (ADR-0019), and record
Expand DownExpand Up@@ -315,7 +315,7 @@ manifest: {
}
```

**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is deprecated and ignored by the runtime.
**Object naming:** The object `name` is the canonical identifier and equals the physical table name. Embed any domain prefix directly in the name (e.g. `name: 'crm_account'`); the object-level `namespace` *field* is retired (ADR-0129 D3) and refused at load.

**`manifest.namespace` (ADR-0048):** Optional, but **enforced once set**. When a package declares `manifest.namespace: 'crm'`, every `object.name` must start with `crm_` or `defineStack` errors (`validateNamespacePrefix` in `@objectstack/spec`); the legacy `<ns>__<short>` double-underscore form is rejected, and `sys_`-prefixed names are platform-reserved and exempt. The namespace is also a package-ownership key — installing two packages that both claim `crm` fails with `NamespaceConflictError` (downgrade to a warning with `OS_METADATA_COLLISION=warn`). `os lint` additionally emits a non-fatal `naming/namespace-prefix` warning for bare-named UI/automation items (app, page, dashboard, flow, action, report, dataset) when a namespace is set.

Expand DownExpand Up@@ -576,7 +576,7 @@ PORT=8080 os start # production — pin the port explicitly (see Ports & netwo

A minimal but complete project from scratch:

**`package.json`** (mirrors the `blank` template):
**`package.json`**:
```json
{
"name": "my-todo-app",
Expand All@@ -588,13 +588,13 @@ A minimal but complete project from scratch:
"validate": "objectstack validate"
},
"dependencies": {
"@objectstack/spec": "^16.0.0-rc.1",
"@objectstack/runtime": "^16.0.0-rc.1",
"@objectstack/driver-memory": "^16.0.0-rc.1",
"@objectstack/plugin-hono-server": "^16.0.0-rc.1"
"@objectstack/spec": "^17.0.0",
"@objectstack/runtime": "^17.0.0",
"@objectstack/driver-memory": "^17.0.0",
"@objectstack/plugin-hono-server": "^17.0.0"
},
"devDependencies": {
"@objectstack/cli": "^16.0.0-rc.1",
"@objectstack/cli": "^17.0.0",
"typescript": "^6.0.0"
}
}
Expand DownExpand Up@@ -741,7 +741,7 @@ import { ObjectKernel } from '@objectstack/core';

const kernel = new ObjectKernel({
logger: {
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
level: 'info', // debug|info|warn|error|fatal|silent
format: 'json', // 'json' | 'text' | 'pretty'
},
defaultStartupTimeout: 30000, // Per plugin (ms)
Expand DownExpand Up@@ -772,7 +772,7 @@ import type { Plugin, PluginContext } from '@objectstack/core';
export interface Plugin {
name: string; // Unique identifier (reverse domain recommended)
version?: string; // Semantic version
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql
dependencies?: string[]; // Plugins that must init before this one

// Phase 1: Register services
Expand Down
2 changes: 1 addition & 1 deletion skills/objectstack-platform/rules/plugin-lifecycle.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ export interface Plugin {
version?: string;

/** Plugin type */
type?: string; // 'standard' | 'ui' | 'driver' | 'server' | 'app' | 'theme' | 'agent'
type?: string; // standard|ui|driver|server|app|theme|agent|objectql

/** Plugins that must init before this one */
dependencies?: string[];
Expand Down
12 changes: 6 additions & 6 deletions skills/objectstack-platform/rules/service-registry.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -158,34 +158,34 @@ The REST plugin (`com.objectstack.rest.api`, `@objectstack/rest`) registers

## Core Fallback Injection

ObjectKernel auto-injects in-memory fallbacks for `core`-criticality services not registered by any plugin during Phase 1.
ObjectKernel auto-injects an in-memory fallback for each `core` service that has one and no plugin registered in Phase 1.

```
Phase 1: init() completes for all plugins
Kernel checks ServiceRequirementDef (@objectstack/spec/system):
'data' → required → ERROR if missing (no fallback; ObjectQLPlugin registers it)
'data' → required → ERROR if missing (ObjectQLPlugin registers it)
'metadata' → core → auto-inject createMemoryMetadata() if missing
'cache' → core → auto-inject createMemoryCache() if missing
'queue' → core → auto-inject createMemoryQueue() if missing
'job' → core → auto-inject createMemoryJob() if missing
'job' → core → NO fallback — warns; getService throws if missing
'i18n' → core → auto-inject createMemoryI18n() if missing
'auth' → core → no fallback factory — degraded-capability warning if missing
'auth' → core → NO fallback — warns; getService throws if missing
'realtime' → optional → skip, plugins should check availability
Phase 2: start() begins — all core services available
```

The fallbacks are **factories** exported from `@objectstack/core`
(`createMemoryCache`, `createMemoryMetadata`, `createMemoryQueue`,
`createMemoryJob`, `createMemoryI18n`) — not classes.
`createMemoryI18n`) — not classes; `job`/`auth` have none.

### Service Criticality Levels

| Level | Behavior |
|:------|:---------|
| `required` | Kernel throws if missing — system cannot start |
| `core` | Auto-injected in-memory fallback if no plugin provides it |
| `core` | In-memory fallback auto-injected where one exists, else warn |
| `optional` | Silently skipped — plugins must check before use |

## Incorrect vs Correct
Expand Down
Loading